2017-10-04 65 views
1

的一个节点我有这个JSON在我的数据库:PostgreSQL的 - NoSQL的查询思路选择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受影响的行的回报。

文档:

https://www.postgresql.org/docs/current/static/datatype-json.html https://www.postgresql.org/docs/current/static/functions-json.html

每一个帮助是值得欢迎!

回答

2

讲起每个查询的第一:

select data#>'{Questions}' from db.my_table 
where (data #> '{Questions,0,QuestionId}')::numeric = 6; 

这实际上失败(ERROR: cannot cast type json to numeric)。您可以将where子句中的运算符更改为#>>,并且不会再有错误 - #>>返回可以转换为数字的文本。在这一点上,查询将返回整个Questions数组,但是,而不是您想要的具体问题。

为什么?因为所有的问题都是同一行的一部分。

SELECT返回行,其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数组并将每个元素作为一行返回单列(名为“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; 

好吧,让我们分析一下。最终,它返回我们使用json_array_elements调用创建的datatable表的question字段。 question是一个json对象,我们过滤只返回QuestionID == 6的对象。

但请注意,我们也从my_table中选择,因为最终这是数据的来源。在这种情况下,我们在my_tabledatatable之间进行无约束的笛卡尔连接。这不好,可能不会很好地扩展。但它适用于我们目前只有几行的情况。

希望给你一个开始的地方。

+0

嘿@jmelesky感谢您的回应!但我有以下错误: '错误:函数json_array_elements(jsonb)不存在 线1:从db.m选择json_array_elements(数据 - >'问题')... ^ 提示:没有函数匹配给定名称和参数类型。您可能需要添加显式类型转换。 **********错误**********'当我运行最后一个查询(笛卡尔)。我的专栏是jsonb ... – IgoR

+1

如果您的专栏是jsonb,而不是json,那么您应该使用jsonb功能而不是json功能。正如[documentation](https://www.postgresql.org/docs/current/static/functions-json.html#FUNCTIONS-JSON-PROCESSING-TABLE)所示,这意味着使用'jsonb_array_elements',而不是'json_array_elements '。将来,在你的问题中提供关于你的模式的更多信息将会有所帮助。 – jmelesky

+0

!非常感谢你,现在的作品......我会提供一些有关我的模式的信息,以便你能看到一个可能的“最佳解决方案”。 :) – IgoR