Postgres 9.6 - поле jsonb сложного запроса, состоящее из массива jsons - PullRequest
0 голосов
/ 06 мая 2018

Мой стол выглядит примерно так:

CREATE TABLE myjsontable(data JSONB NOT NULL);

INSERT INTO myjsontable VALUES ('[{"score":20 ,"category": 10 }, {"score":100 ,"category": 100 },{"score":500 ,"category": 50 }]');

INSERT INTO myjsontable VALUES ('[{"score":1000 ,"category": 40 }, {"score":30 ,"category": 50 },{"score":6000 ,"category": 100 }]');

INSERT INTO myjsontable VALUES ('[{"score":10 ,"category": 1 }, {"score":123 ,"category": 40 },{"score":1000 ,"category": 50 }]');

CREATE INDEX ON myjsontable USING GIN(data);

Я хочу получить только записи, которые имеют категории X и балл выше Y для конкретного json в массиве jsons

Все, что мне удалось сделать, это использовать вот так:

SELECT * FROM myjsontable WHERE data @> '[{ "category": 10}]';

Я хотел бы сделать что-то вроде для простого запроса (например, NoSQL ..)

 SELECT * FROM myjsontable WHERE data @> '[{ "category": 10, "score": ">10" }]';

Есть ли способ сделать простые, но сложные, где предложения, как в примере, приведенном, когда мое поле представляет собой массив jsons?

1 Ответ

0 голосов
/ 06 мая 2018

, поскольку категория и оценка хранятся в виде объектов json в массиве json, сначала массив должен быть unnested, а затем с помощью функции доступа json сравниваются значения в предложении where. Необходимо преобразовать JSON в текст перед преобразованием в INT:

SELECT t.* 
FROM myjsontable t
CROSS JOIN JSONB_ARRAY_ELEMENTS(data) x
WHERE (x.value->>'category')::INT = 10 
  AND (x.value->>'score')::INT > 10

Также можно написать этот запрос, используя предложение EXISTS. Эта формулировка немного более ясна по своему намерению:

SELECT * FROM myjsontable 
WHERE EXISTS (SELECT TRUE FROM JSONB_ARRAY_ELEMENTS(data) x
              WHERE (value->>'category')::INT = 10 
                AND (value->>'score')::INT > 10)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...