IBM Db2 查询未返回 JSON 数组对象的预期结果

问题描述 投票:0回答:2

我正在使用 IBM Db2(版本 11.5),并且尝试查询存储在名为 data 的列中的 JSON 数据,该列包含对象数组。但是,我使用 JSON_EXISTS 的查询没有返回预期结果。

JSON 结构示例

JSON结构(此处简化)包含一个数组outerField,我需要检索其中存在outerField对象且innerField等于“target”的行。但是,我使用 JSON_EXISTS 的查询没有返回预期结果。

数据列中存储的简化 JSON 数据如下所示:

{
  "randomField1": "randomValue",
  ...
  "outerField":
    [
      {
        "innerField": "target"
      },
      {
        "innerField": "dummy1"
      },
      {
        "innerField": "dummy2"
      }
    ]
}

使用 Json 路径和 JSON_EXIST

我想使用 JSON Path,并使用在线评估工具,我发现这个查询应该可以工作:

$.outerField[?(@.innerField== "target")].

鉴于我不能直接使用 JSON_VALUE 和 json 路径,例如:

JSON_VALUE(data, '$.outerField[*].innerField') = 'target'

因为 JSON_VALUE 只需要一个值(outerField[0].innerFieldworks 如预期)。

我认为我可以使用 Db2 的 JSON_EXISTS 函数:

SELECT *
FROM test_entity
WHERE JSON_EXISTS(
    data,
    '$.outerField[?(@.innerField== "target")]'
)

不幸的是,即使示例 JSON 清楚地显示了outerField 中的对象,且innerField 等于“target”,也不会返回任何行。

有什么想法或建议吗?

** 编辑 **

我认为最合理的解决方案是使用 JSON_TABLE 函数取消嵌套内部数组,但我不确定如何继续。我可以在普通字段上使用 JSON_TABLE,但对于数组,我会遇到许多语法错误。例如:

SELECT *
FROM TEST_ENTITY te, JSON_TABLE(te.data, 'lax $.outerField[*]' columns (target VARCHAR(100) PATH 'lax $.innerField') ERROR ON ERROR)  AS jt 
WHERE jt.innerField= 'target';

此查询返回以下错误

SQL Error [42601]: An unexpected token "lax $.outerField[*]" was found following "".  Expected tokens may include:  "strict $".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.31.10

(即使使用严格而不是宽松,我也收到相同的错误)

sql db2 jsonpath json-table
2个回答
0
投票
SELECT * FROM test_entity
where json_exists(data, '$?(@.outerField[*].innerField == "target")') ;

0
投票

考虑到我对(糟糕,非常糟糕)DB2 相关文档感到沮丧,我以一种有点“奇特”的方式管理了这项任务。

我不确定这是否是最好的解决方案,但目前有效。 我发现我可以使用 JSON_QUERY 来提取和展平 JSON 对象中的嵌套数组。

就像这样:

SELECT JSON_QUERY(tt.JSONDOC, '$.outerField[*].innerField' WITH UNCONDITIONAL WRAPPER)
FROM TEST_TABLE tt

此查询返回:

-------------------+
["targetB"]        |
["target"]         |
["dummy1"]         |
["dummy2"]         |
["target","dummy3"]|

如您所见,结果包含每行的innerField 值的扁平化CLOB。所以我意识到我可以在 WHERE 子句中使用这种方法从一开始就根据需要过滤行。

这是查询结果:

SELECT *
FROM EMPLOYEE_TABLE et
WHERE JSON_QUERY(et.JSONDOC, '$.outerField[*].innerField' WITH UNCONDITIONAL WRAPPER) LIKE '%"target"%'

这将返回至少有一个“innerField”等于“目标”值的所有行!

ID|JSONDOC                                                                                                                                                                 |
--+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 2|{"id" : 901,"firstname" : "John","lastname"  : "Doe","phoneno"   : "555-3762""outerField" : [{  "innerField": "target"}]}                                            |
 5|{"id" : 901,"firstname" : "John","lastname"  : "Doe","phoneno"   : "555-3762""outerField" : [{  "innerField": "target"},{  "innerField": "dummy3"}]}|
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.