Postgres 9.6 - 包含jsons

时间:2018-05-06 15:12:00

标签: postgresql postgres-9.6

我的表看起来像这样:

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);

我想只获取在jsons数组中特定json上的类别X 得分高于Y的记录

我所做的就是使用像这样的包含:

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

我希望我可以做一些简单的查询(比如NoSQL ..)

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

有没有办法做简单但复杂的,在我的字段是jsons数组时给出的例子中的子句?

1 个答案:

答案 0 :(得分:1)

因为类别&得分作为json对象存储在json数组中,首先必须对数组进行unnested,然后使用json访问器函数将where子句中的值进行比较。在转换为int:

之前,必须将json转换为文本
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)