HiveQL:如何编写查询以根据嵌套的 JSON 数组值选择和过滤记录
Posted
技术标签:
【中文标题】HiveQL:如何编写查询以根据嵌套的 JSON 数组值选择和过滤记录【英文标题】:HiveQL: How to write a query to select and filter records based on nested JSON array values 【发布时间】:2021-01-08 18:38:54 【问题描述】:在我们的日志数据库中,我们将自定义 UI 数据存储为序列化的 JSON 字符串。我一直在使用 lateral view json_tuple() 来遍历 JSON 对象并提取嵌套值。但是,我需要根据对象数组是否包含某些值来过滤我的一些查询结果。在进行了一些挖掘之后,我认为我需要使用 lateral view explode(),但我不是 HiveQL 专家,我不确定如何在我需要的方式。
EX:(为了清晰和简洁而简化)
// ui_events table schema
eventDate, eventType, eventData
// serialized JSON string stored in eventData
foo: bar: [ x: 1, y: 0 , x: 0, y: 1 ]
// HiveQL query
select
eventDate,
x,
y
from ui_events
lateral view json_tuple(eventData, 'foo') as foo
lateral view json_tuple(foo, 'bar') as bar
// <-- how to select only sub-item(s) in bar where x = 0 and y = 1
where
eventType = 'custom'
and // <-- how to only return records where at least 1 `bar` item was found above?
任何帮助将不胜感激。谢谢!
【问题讨论】:
bar: [ x: 1, y: 0 ], x: 0, y: 1 ] -- 中间多余的方括号? 抱歉,这是一个错字,我现在已经更正了。 这个 JSON 也不正确。键和字符串值应加引号:“bar”、“x”等 @leftjoin 再次,为了简洁/清晰起见,我进行了简化。 JSON 的 IRL 格式正确。 【参考方案1】:读取代码中的 cmets。您可以根据需要过滤数据集:
with
my_table as(
select stack(2, ' "foo": "bar": [ "x": 1, "y": 0 , "x": 0, "y": 1 ] ',
' "foo": '
) as EventData
)
select * from
(
select --get_json_object returns string, not array.
--remove outer []
--and replace delimiter between , with ,,,
--to be able to split array
regexp_replace(regexp_replace(get_json_object(EventData, '$.foo.bar'),'^\\[|\\]$',''),
'\\,\\', ',,,'
)bar
from my_table t
) s --explode array
lateral view explode (split(s.bar,',,,')) b as bar_element
--get struct elements
lateral view json_tuple(b.bar_element, 'x','y') e as x, y
结果:
s.bar b.bar_element e.x e.y
"x":1,"y":0,,,"x":0,"y":1 "x":1,"y":0 1 0
"x":1,"y":0,,,"x":0,"y":1 "x":0,"y":1 0 1
【讨论】:
以上是关于HiveQL:如何编写查询以根据嵌套的 JSON 数组值选择和过滤记录的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 EMR 上的 HiveQL 将 DynamoDB 上的 Map 数据类型列导出到具有 JSON 数据类型的 S3?