带有JSON格式消息的KSQL EXTRACTJSONFIELD返回null

时间:2018-09-26 18:18:01

标签: apache-kafka ksql

使用带有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。

2 个答案:

答案 0 :(得分:1)

在最新版本中,JSON解析器ksql issues #1562似乎发生了实质性变化,该变化将VARCHAR列中的JSON内容中的引号剥离(如您从我的示例中看到的),这导致JSON解析器找不到该字段名称。

该问题建议使用STRUCT代替EXTRACTJSONFIELD(与我上面的工作示例一样)。

这似乎不适合我的用例,因为我的深字段名称可能会更改。将对此进行更多研究并进行更新。

答案 1 :(得分:1)

ksql issues #1562已解决,您应该能够像以前一样使用EXTRACTJSONFIELD函数。请注意,您现在需要使用母版的最新版本才能具有此功能。