使用带有kafka主题的KSQL-CLI,该主题的消息是JSON对象。我希望提取诸如obj.updaterId之类的字段,而无需声明详尽的STRUCT或MAP字段定义。
{ "id": "5ba8f7e6b93c7964efb00f48", "source": "ShareService", "obj": { "updaterId": "systems@test.com", "desc": "foobar", "name": "com.test.auto.sensor" } }
我可以通过多种方式成功创建Stream,最简单的方法是:
CREATE STREAM objs1 (obj VARCHAR) WITH (kafka_topic='json-topic', value_format='JSON');
简单选择可以正常工作,您可以看到obj ...
的内容。SELECT * FROM objs1;
1537804190394 | “ 5ba8f7e6b93c7964efb00f48” | {name = com.test.auto.sensor, updaterId = systems @ test.com,desc = foobar}
这里不起作用的是任何尝试使用EXTRACTJSONFIELD从obj提取JSON字段的尝试。对顶级对象和嵌套对象的响应均为“ null”。
SELECT EXTRACTJSONFIELD(obj, '$.updaterId') AS updater FROM objs1;
空
the ksql documentation中有一条注释,指出如果数据是STRING列中的实际对象,我可以改为使用STRUCT。并不是说我必须使用STRUCT。
顺便说一句,使用STRUCT确实可以,但是,我对EXTRACTJSONFIELD感兴趣,因为消息的深层结构会有所不同。换句话说,如果消息不包含深层结构,则有时会期望为空响应。
作品:
CREATE STREAM objs1 (obj STRUCT<updaterId VARCHAR>) WITH (kafka_topic='json-topic', value_format='JSON');
SELECT OBJ->updaterId AS updater FROM OBJS1;
我发誓我会在其他人的问题中看到其他示例,这些示例似乎也适用于类似的安排。我想念什么?
注意:我已经简化了本文的JSON。我相信它是更大且嵌套的IRL,但我认为这个简单的示例是正确的。
OSX上的KSQL版本5.0.0。
答案 0 :(得分:1)
在最新版本中,JSON解析器ksql issues #1562似乎发生了实质性变化,该变化将VARCHAR列中的JSON内容中的引号剥离(如您从我的示例中看到的),这导致JSON解析器找不到该字段名称。
该问题建议使用STRUCT代替EXTRACTJSONFIELD(与我上面的工作示例一样)。
这似乎不适合我的用例,因为我的深字段名称可能会更改。将对此进行更多研究并进行更新。
答案 1 :(得分:1)
ksql issues #1562已解决,您应该能够像以前一样使用EXTRACTJSONFIELD
函数。请注意,您现在需要使用母版的最新版本才能具有此功能。