是这样的,最近公司打算上 impala 来做快查,但是在复杂类型( map 、array 、struct )上面有很大的问题。 impala 和 hive 大部分时候都能兼容,偶尔兼容不了想想办法也能凑合过去,这个问题我实在是没辙了,各位老哥帮忙想想办法。
impala 访问复杂类型的方式过于奇葩,比如 map 吧,他不支持中括号的方式访问通过键访问值,而是必须以这种方式(来自官方文档):
DESCRIBE table_0; +---------+-----------------------+ | name | type | +---------+-----------------------+ | field_0 | string | | field_1 | map<string,int> | ... SELECT field_0, map_field.key, map_field.value FROM table_0, table_0.field_1 AS map_field WHERE length(field_0) = 1 LIMIT 10; +---------+-----------+-------+ | field_0 | key | value | +---------+-----------+-------+ | b | gshsgkvd | NULL | | b | twrtcxj6 | 18 | | b | 2vp5 | 39 | | b | fh0s | 13 | | v | 2 | 41 | | v | 8b58mz | 20 | | v | hw | 16 | | v | 65l388pyt | 29 | | v | 03k68g91z | 30 | | v | r2hlg5b | NULL | +---------+-----------+-------+ 同时复杂类型的值不支持出现在任何 select list 中,也就是说在子查询中传递复杂类型给父查询是行不通的,必须展开再传递展开后的基本类型!这个是没法凑合的,一方面公司的数据开发人员肯定不会习惯这种语法,另一方面公司已经有大量的 hive 查询的语句了,本来打算了 impala 之后写个语法转换器把 hive 的查询转成 impala 的,但由于这个复杂类型的问题,拓扑结构都变了,我甚至觉得理论上很多逻辑都是没法用 impala 这种受限的语法复现的。(这只是我的直觉,当然如果哪位老哥能给资料证明两种形式表达能力相同,有转换的方式,小弟感激不尽~)
我能想到的解决办法就是用 udf,参考 https://blog.csdn.net/yu616568/article/details/79198501 这篇文章,把所有的复杂类型都看成 string,再用自己写的 udf 去解析它、根据键取值啥的,由于是用 C++写的,所以速度上应该也不会慢到哪里去。
但是这样还是有问题没解决,impala 不支持 lateral view,也就是列转行,而我们之前的 hive 查询中有大量此类语句,这个就没法通过 udf 解决了,毕竟 udf 也只能传进去基础类型、传出来基础类型,并没有改变拓扑结构的能力,而我找了半天,impala 中唯一可能成为替代品的就是复杂类型的展开了,可以把列转成行,可是这样又绕回来了,impala 中的复杂类型就是个坑,唉。
各位老哥,求教这个问题有可能解决吗,在不换掉 impala 的情况下,少许对 impala 的二次开发也是可以接受的。
