PostgreSql中Jsonb对象解析
Jsonb object parsing in PostgreSql
如何在 PostgreSql 中解析 jsonb 对象。问题是 - 对象每次都因内部结构而异。就像下面一样。
{
"1":{
"1":{
"level":2,
"nodeType":2,
"id":2,
"parentNode":1,
"attribute_id":363698007,
"attribute_text":"Finding site",
"concept_id":386108004,
"description_text":"Heart tissue",
"hierarchy_id":0,
"description_id":-1,
"deeperCnt":0,
"default":false
},
"level":1,
"nodeType":1,
"id":1,
"parentNode":0,
"concept_id":22253000,
"description_id":37361011,
"description_text":"Pain",
"hierarchy_id":404684003,
"deeperCnt":1,
"default":false
},
"2":{
"1":{
"attribute_id":"363698007",
"attribute_text":"Finding site (attribute)",
"value_id":"321667001",
"value_text":"Respiratory tract structure (body structure)",
"default":true
},
"level":1,
"nodeType":1,
"id":3,
"parentNode":0,
"concept_id":11833005,
"description_id":20419011,
"description_text":"Dry cough",
"hierarchy_id":404684003,
"deeperCnt":1,
"default":false
},
"level":0,
"recAddedLevel":1,
"recAddedId":3,
"nodeType":0,
"multiple":false,
"currNodeId":3,
"id":0,
"lookForAttributes":false,
"deeperCnt":2,
}
那么我应该如何解析所有对象,例如查看对象内部是否有 "attribute_id" = 363698007?
在这种情况下,我们应该在 PostgreSql 中使用 WHERE 语句 'true' 而 selecting 数据行。
2 个问题 - 我应该为 jsonb 列使用什么索引以获得想要的结果?
已经尝试创建 btree 和 gin 索引,但即使是简单的 select returns 'null' 和 sql 也像这样:
SELECT object::jsonb -> 'id' AS id
FROM table;
如果我使用这个:
SELECT object
FROM table;
returns首先描述对象。
快速而肮脏的方式(扩展到):
WITH RECURSIVE doc_key_and_value_recursive(id, key, value) AS (
SELECT
my_json.id,
t.key,
t.value
FROM my_json, jsonb_each(my_json.data) AS t
UNION ALL
SELECT
doc_key_and_value_recursive.id,
t.key,
t.value
FROM doc_key_and_value_recursive,
jsonb_each(CASE
WHEN jsonb_typeof(doc_key_and_value_recursive.value) <> 'object' THEN '{}'::jsonb
ELSE doc_key_and_value_recursive.value
END) AS t
)
SELECT t.id, t.data->'id' AS id
FROM doc_key_and_value_recursive AS c
INNER JOIN my_json AS t ON (t.id = c.id)
WHERE
jsonb_typeof(c.value) <> 'object'
AND c.key = 'attribute_id'
AND c.value = '363698007'::jsonb;
在线示例:https://dbfiddle.uk/?rdbms=postgres_11&fiddle=57b7c4e817b2dd6580bbf28cbac10981
一旦找到相关键和值就停止递归,反向排序和限制 1,这可能会得到很大改善。但它一般会做基本的事情。
它还表明 jsonb->'id'
确实按预期工作。
如何在 PostgreSql 中解析 jsonb 对象。问题是 - 对象每次都因内部结构而异。就像下面一样。
{
"1":{
"1":{
"level":2,
"nodeType":2,
"id":2,
"parentNode":1,
"attribute_id":363698007,
"attribute_text":"Finding site",
"concept_id":386108004,
"description_text":"Heart tissue",
"hierarchy_id":0,
"description_id":-1,
"deeperCnt":0,
"default":false
},
"level":1,
"nodeType":1,
"id":1,
"parentNode":0,
"concept_id":22253000,
"description_id":37361011,
"description_text":"Pain",
"hierarchy_id":404684003,
"deeperCnt":1,
"default":false
},
"2":{
"1":{
"attribute_id":"363698007",
"attribute_text":"Finding site (attribute)",
"value_id":"321667001",
"value_text":"Respiratory tract structure (body structure)",
"default":true
},
"level":1,
"nodeType":1,
"id":3,
"parentNode":0,
"concept_id":11833005,
"description_id":20419011,
"description_text":"Dry cough",
"hierarchy_id":404684003,
"deeperCnt":1,
"default":false
},
"level":0,
"recAddedLevel":1,
"recAddedId":3,
"nodeType":0,
"multiple":false,
"currNodeId":3,
"id":0,
"lookForAttributes":false,
"deeperCnt":2,
}
那么我应该如何解析所有对象,例如查看对象内部是否有 "attribute_id" = 363698007? 在这种情况下,我们应该在 PostgreSql 中使用 WHERE 语句 'true' 而 selecting 数据行。
2 个问题 - 我应该为 jsonb 列使用什么索引以获得想要的结果? 已经尝试创建 btree 和 gin 索引,但即使是简单的 select returns 'null' 和 sql 也像这样:
SELECT object::jsonb -> 'id' AS id
FROM table;
如果我使用这个:
SELECT object
FROM table;
returns首先描述对象。
快速而肮脏的方式(扩展到
WITH RECURSIVE doc_key_and_value_recursive(id, key, value) AS (
SELECT
my_json.id,
t.key,
t.value
FROM my_json, jsonb_each(my_json.data) AS t
UNION ALL
SELECT
doc_key_and_value_recursive.id,
t.key,
t.value
FROM doc_key_and_value_recursive,
jsonb_each(CASE
WHEN jsonb_typeof(doc_key_and_value_recursive.value) <> 'object' THEN '{}'::jsonb
ELSE doc_key_and_value_recursive.value
END) AS t
)
SELECT t.id, t.data->'id' AS id
FROM doc_key_and_value_recursive AS c
INNER JOIN my_json AS t ON (t.id = c.id)
WHERE
jsonb_typeof(c.value) <> 'object'
AND c.key = 'attribute_id'
AND c.value = '363698007'::jsonb;
在线示例:https://dbfiddle.uk/?rdbms=postgres_11&fiddle=57b7c4e817b2dd6580bbf28cbac10981
一旦找到相关键和值就停止递归,反向排序和限制 1,这可能会得到很大改善。但它一般会做基本的事情。
它还表明 jsonb->'id'
确实按预期工作。