2015-09-09 1 views
1

Итак, я уже видел несколько других ответов на этот вопрос в StackOverflow, но ни один из них не работал для меня.Запрос PostgreSQL JsonB для объекта в массиве JSON на основе атрибутов объекта

{ 
    "data": { 
     "list": [ 
      {"id": "2ac5bf6f-bc4a-49e8-8f9f-bc518a839981", "type": "type1"}, 
      {"id": "d15ac090-11ce-4c0c-a05d-d4238f01e8b0", "type": "type3"}, 
      {"id": "b98958fa-87c4-4dcc-aa84-beaf2b32c5c0", "type": "type1"}, 
      {"id": "854f4d2a-f37c-42cb-9a1f-17a15454a314", "type": "type2"}, 
      {"id": "555816da-4547-4a82-9e7e-1e92515bd82b", "type": "type2"}, 
      {"id": "0f7f4ced-61c2-45da-b15c-0e12058f66a7", "type": "type4"} 

     ] 
    } 
} 

Этот Json хранится в поле под названием «вопросы», теперь я хочу, чтобы запросить эту таблицу для объекта с определенным идентификатором в списке. Так что у меня есть идентификатор 555816da-4547-4a82-9e7e-1e92515bd82b, я хотел бы вернуться

{"id": "555816da-4547-4a82-9e7e-1e92515bd82b", "type": "type2"} 

Решения этого я видел в интернете (в основном здесь), которые не работали здесь:

SELECT questions->'data'->'list' 
FROM assignments 
WHERE id='81asd6230-126d-4bc8-9745-c4333338115c' 
AND questions->'data'->'list' @> '[{"id":"854f4d2a-f37c-42cb-9a1f-17a15454a314"}]'; 

I видели это решение на нескольких разных ответах, но он не сужает массив вообще, он возвращает всю вещь каждый раз. Первый id в предложении where - это идентификатор конкретного объекта назначения, который я хочу, в основном это не имеет значения.

SELECT questions->'data'->'list' 
FROM assignments 
WHERE id='81asd6230-126d-4bc8-9745-c4333338115c' 
AND questions->'data'->'list' @> '[{"id":"854f4d2a-f37c-42cb-9a1f-17a15454a314"}]'; 

Это ничего не возвращает.

У кого-нибудь есть идея, как это сделать легко?

ответ

2

Вы можете использовать функцию jsonb_array_elements(jsonb), чтобы выбрать все элементы массива JSon:

select jsonb_array_elements(questions->'data'->'list') elem 
from assignments 
where id='81asd6230-126d-4bc8-9745-c4333338115c' 

           elem 
----------------------------------------------------------------- 
{"id": "2ac5bf6f-bc4a-49e8-8f9f-bc518a839981", "type": "type1"} 
{"id": "d15ac090-11ce-4c0c-a05d-d4238f01e8b0", "type": "type3"} 
{"id": "b98958fa-87c4-4dcc-aa84-beaf2b32c5c0", "type": "type1"} 
{"id": "854f4d2a-f37c-42cb-9a1f-17a15454a314", "type": "type2"} 
{"id": "555816da-4547-4a82-9e7e-1e92515bd82b", "type": "type2"} 
{"id": "0f7f4ced-61c2-45da-b15c-0e12058f66a7", "type": "type4"} 
(6 rows) 

Используйте приведенный выше запрос, если вы хотите, чтобы выбрать элемент с конкретным id:

select elem 
from (
    select jsonb_array_elements(questions->'data'->'list') elem 
    from assignments 
    where id='81asd6230-126d-4bc8-9745-c4333338115c' 
    ) sub 
where elem->>'id' = '854f4d2a-f37c-42cb-9a1f-17a15454a314' 

           elem 
----------------------------------------------------------------- 
{"id": "854f4d2a-f37c-42cb-9a1f-17a15454a314", "type": "type2"} 
(1 row) 
+0

Cool, это работает , как мне сделать обновление в аналогичной ситуации, где у меня есть идентификатор вопроса и вы хотите обновить его атрибут типа? – user1032369

+0

В Postgres 9.4 нет функций для изменения элементов jsonb. Вы можете обновить значение jsonb в целом. См. Соответствующие ответы: [Как изменить поля внутри нового типа данных PostgreSQL JSON?] (Http://stackoverflow.com/questions/18209625/how-do-i-modify-fields-inside-the-new-postgresql-json -datatype) и [Обновить некоторые элементы массива json-массива в PostgreSQL 9.4] (http://stackoverflow.com/questions/27288768/update-certain-array-elements-of-a-json-array-in-postgresql- 9-4). – klin

+0

В [Postgres 9.5] (http://www.postgresql.org/docs/9.5/static/functions-json.html) вы сможете использовать функцию 'jsonb_set()'. – klin

Смежные вопросы