PostgreSQL - NoSQL 查询思路 select JSON 的一个节点
PostgreSQL - NoSQL query ideas to select one node of JSON
我的数据库中有这个 JSON:
{
"Id": 1,
"Questions": [
{
"QuestionId": 6,
"Description": "Question 1",
"Alternatives": [
{
"Index": 1,
"CorrectAnswer": false,
"AlternativeId": 26,
"QuestionId": 6,
"Description": "Alternative one",
"Selected": false
},
{
"Index": 2,
"CorrectAnswer": true,
"AlternativeId": 27,
"QuestionId": 6,
"Description": "Alternative two",
"Selected": false
}
]
},
{
"QuestionId": 7,
"Description": "Question 2",
"Alternatives": [
{
"Index": 1,
"CorrectAnswer": false,
"AlternativeId": 26,
"QuestionId": 6,
"Description": "Alternative one",
"Selected": false
},
{
"Index": 2,
"CorrectAnswer": true,
"AlternativeId": 27,
"QuestionId": 6,
"Description": "Alternative two",
"Selected": false
}
]
}
]
}
我无法在本文档中得到一个问题。我尝试了以下查询:
select data#>'{Questions}' from db.my_table
where (data #> '{Questions,0,QuestionId}')::numeric = 6;
SELECT data ->> 'Questions' AS Questions FROM db.my_table
WHERE (data -> 'Questions' ->> 'QuestionId')::numeric = 6;
SELECT data ->> 'Questions' AS Questions FROM db.my_table
WHERE data -> 'Questions' ->> 'QuestionId' = '6'
我做错了什么?我总是得到 0 行的 return。
文档:
https://www.postgresql.org/docs/current/static/datatype-json.html
https://www.postgresql.org/docs/current/static/functions-json.html
欢迎大家的帮助!
让我们先谈谈您的每一个疑问:
select data#>'{Questions}' from db.my_table
where (data #> '{Questions,0,QuestionId}')::numeric = 6;
这实际上失败了(ERROR: cannot cast type json to numeric
)。可以把where子句中的运算符改成#>>
,就不会再报错--#>>
returns text, which can be cast to numeric.届时,查询将 return 您的整个 Questions
数组,而不是您想要的特定问题。
为什么?因为所有的问题都是同一行的一部分。
SELECT
returns 行,其 WHERE
子句对行进行操作。由于一行中有很多值,因此使用这种方法有条件地提取 json 子对象会遇到麻烦。
其他两个查询 运行 成功但没有产生结果:
SELECT data ->> 'Questions' AS Questions FROM db.my_table
WHERE (data -> 'Questions' ->> 'QuestionId')::numeric = 6;
SELECT data ->> 'Questions' AS Questions FROM db.my_table
WHERE data -> 'Questions' ->> 'QuestionId' = '6'
在这两种情况下,您都在索引 json blob 中不存在的字段。 Questions
是一个数组,因此用字符串索引它不起作用,但 json 足够宽松,可以让您尝试。换句话说,子句 WHERE data -> 'Questions' ->> 'QuestionId' = '6'
根本不匹配任何行。
诀窍是将每个问题排成一行。这有点复杂,但做起来并不难。
首先,查看函数 json_array_elements
,它看起来应该可以工作——它需要一个 json 数组,并且 return 将每个元素作为一行和一列(名为 "value")。乍一看,您似乎应该能够执行以下形式的操作:
SELECT value FROM json_array_elements(...)
WHERE value ->> 'QuestionId'::numeric = 6;
不幸的是,事情并没有那么简单。这是一个有效的查询:
SELECT datatable.question
FROM my_table,
json_array_elements(my_table.data -> 'Questions') AS datatable(question)
WHERE (question->>'QuestionId')::numeric = 6;
好的,让我们分解一下。最终,它是 returning 我们使用 json_array_elements
调用创建的 datatable
table 的 question
字段。 question
是一个 json 对象,我们只过滤 return 对象 QuestionID == 6
.
不过请注意,我们也从 my_table
中进行选择,因为最终数据来自那里。在这种情况下,我们在 my_table
和 datatable
之间进行无约束的笛卡尔连接。这不好,而且可能不会很好地扩展。但它适用于我们目前只有几行的情况。
希望这能给你一个开始的地方。
我的数据库中有这个 JSON:
{
"Id": 1,
"Questions": [
{
"QuestionId": 6,
"Description": "Question 1",
"Alternatives": [
{
"Index": 1,
"CorrectAnswer": false,
"AlternativeId": 26,
"QuestionId": 6,
"Description": "Alternative one",
"Selected": false
},
{
"Index": 2,
"CorrectAnswer": true,
"AlternativeId": 27,
"QuestionId": 6,
"Description": "Alternative two",
"Selected": false
}
]
},
{
"QuestionId": 7,
"Description": "Question 2",
"Alternatives": [
{
"Index": 1,
"CorrectAnswer": false,
"AlternativeId": 26,
"QuestionId": 6,
"Description": "Alternative one",
"Selected": false
},
{
"Index": 2,
"CorrectAnswer": true,
"AlternativeId": 27,
"QuestionId": 6,
"Description": "Alternative two",
"Selected": false
}
]
}
]
}
我无法在本文档中得到一个问题。我尝试了以下查询:
select data#>'{Questions}' from db.my_table
where (data #> '{Questions,0,QuestionId}')::numeric = 6;
SELECT data ->> 'Questions' AS Questions FROM db.my_table
WHERE (data -> 'Questions' ->> 'QuestionId')::numeric = 6;
SELECT data ->> 'Questions' AS Questions FROM db.my_table
WHERE data -> 'Questions' ->> 'QuestionId' = '6'
我做错了什么?我总是得到 0 行的 return。
文档:
https://www.postgresql.org/docs/current/static/datatype-json.html https://www.postgresql.org/docs/current/static/functions-json.html
欢迎大家的帮助!
让我们先谈谈您的每一个疑问:
select data#>'{Questions}' from db.my_table
where (data #> '{Questions,0,QuestionId}')::numeric = 6;
这实际上失败了(ERROR: cannot cast type json to numeric
)。可以把where子句中的运算符改成#>>
,就不会再报错--#>>
returns text, which can be cast to numeric.届时,查询将 return 您的整个 Questions
数组,而不是您想要的特定问题。
为什么?因为所有的问题都是同一行的一部分。
SELECT
returns 行,其 WHERE
子句对行进行操作。由于一行中有很多值,因此使用这种方法有条件地提取 json 子对象会遇到麻烦。
其他两个查询 运行 成功但没有产生结果:
SELECT data ->> 'Questions' AS Questions FROM db.my_table
WHERE (data -> 'Questions' ->> 'QuestionId')::numeric = 6;
SELECT data ->> 'Questions' AS Questions FROM db.my_table
WHERE data -> 'Questions' ->> 'QuestionId' = '6'
在这两种情况下,您都在索引 json blob 中不存在的字段。 Questions
是一个数组,因此用字符串索引它不起作用,但 json 足够宽松,可以让您尝试。换句话说,子句 WHERE data -> 'Questions' ->> 'QuestionId' = '6'
根本不匹配任何行。
诀窍是将每个问题排成一行。这有点复杂,但做起来并不难。
首先,查看函数 json_array_elements
,它看起来应该可以工作——它需要一个 json 数组,并且 return 将每个元素作为一行和一列(名为 "value")。乍一看,您似乎应该能够执行以下形式的操作:
SELECT value FROM json_array_elements(...)
WHERE value ->> 'QuestionId'::numeric = 6;
不幸的是,事情并没有那么简单。这是一个有效的查询:
SELECT datatable.question
FROM my_table,
json_array_elements(my_table.data -> 'Questions') AS datatable(question)
WHERE (question->>'QuestionId')::numeric = 6;
好的,让我们分解一下。最终,它是 returning 我们使用 json_array_elements
调用创建的 datatable
table 的 question
字段。 question
是一个 json 对象,我们只过滤 return 对象 QuestionID == 6
.
不过请注意,我们也从 my_table
中进行选择,因为最终数据来自那里。在这种情况下,我们在 my_table
和 datatable
之间进行无约束的笛卡尔连接。这不好,而且可能不会很好地扩展。但它适用于我们目前只有几行的情况。
希望这能给你一个开始的地方。