在 PGSQL JSONB 中使用部分路径进行深度 JSON 查询?
Deep JSON query with partial path in PGSQL JSONB?
给定多个 JSON 文档,如下所示:
{
id: some_id,
l1: {
f1: [
{
c1: foo,
c2: bar
},
{
c1: foo1,
c2: bar1
},
],
f2: [
{
c3: baz,
c4: bar
},
],
}
}
我如何查询 PostgreSQL JSONB for f1....c1: foo1 -- 即没有给出 lX,也没有给出 c1-c2 子文档的列表位置。
这不是 的副本,因为那是关于 MySQL 而这个是关于 PgSQL JSONB。
这里您需要遍历路径 {l1,f1}
#> - operator gets JSON object at specified path; after that, check if any of sub-documents contains '{"c1":"foo1"}'::jsonb
element - @> 的元素列表(运算符检查左 JSON 值是否包含右值):
WITH t(val) AS ( VALUES
('{
"id": "some_id",
"l1": {
"f1": [
{
"c1": "foo",
"c2": "bar"
},
{
"c1": "foo1",
"c2": "bar1"
}
],
"f2": [
{
"c3": "baz",
"c4": "bar"
}
]
}
}'::JSONB)
)
SELECT f1_array_element AS output
FROM
t,jsonb_array_elements(t.val#>'{l1,f1}') AS f1_array_element
WHERE f1_array_element @> '{"c1":"foo1"}'::JSONB;
结果:
output
------------------------------
{"c1": "foo1", "c2": "bar1"}
(1 row)
更新
如果我们不知道确切的 lX
位置,我们需要遍历每个子文档,而不是遍历每个 fX
;查询如下:
SELECT count(*)
FROM
t,
jsonb_each(t.val#>'{l1}') AS fX_sub_doc,
jsonb_array_elements(fX_sub_doc.value) AS cX_sub_doc
WHERE
cX_sub_doc @> '{"c1":"foo1"}';
给定多个 JSON 文档,如下所示:
{
id: some_id,
l1: {
f1: [
{
c1: foo,
c2: bar
},
{
c1: foo1,
c2: bar1
},
],
f2: [
{
c3: baz,
c4: bar
},
],
}
}
我如何查询 PostgreSQL JSONB for f1....c1: foo1 -- 即没有给出 lX,也没有给出 c1-c2 子文档的列表位置。
这不是
这里您需要遍历路径 {l1,f1}
#> - operator gets JSON object at specified path; after that, check if any of sub-documents contains '{"c1":"foo1"}'::jsonb
element - @> 的元素列表(运算符检查左 JSON 值是否包含右值):
WITH t(val) AS ( VALUES
('{
"id": "some_id",
"l1": {
"f1": [
{
"c1": "foo",
"c2": "bar"
},
{
"c1": "foo1",
"c2": "bar1"
}
],
"f2": [
{
"c3": "baz",
"c4": "bar"
}
]
}
}'::JSONB)
)
SELECT f1_array_element AS output
FROM
t,jsonb_array_elements(t.val#>'{l1,f1}') AS f1_array_element
WHERE f1_array_element @> '{"c1":"foo1"}'::JSONB;
结果:
output
------------------------------
{"c1": "foo1", "c2": "bar1"}
(1 row)
更新
如果我们不知道确切的 lX
位置,我们需要遍历每个子文档,而不是遍历每个 fX
;查询如下:
SELECT count(*)
FROM
t,
jsonb_each(t.val#>'{l1}') AS fX_sub_doc,
jsonb_array_elements(fX_sub_doc.value) AS cX_sub_doc
WHERE
cX_sub_doc @> '{"c1":"foo1"}';