Postgresql 用于多个键/值对的PostgresSQL嵌套jsonb查询
从JSONB数据类型开始,我希望有人能帮助我 我有一个表(properties),有两列(id作为主键,data作为jsonb)。 数据结构为:Postgresql 用于多个键/值对的PostgresSQL嵌套jsonb查询,postgresql,postgresql-10,Postgresql,Postgresql 10,从JSONB数据类型开始,我希望有人能帮助我 我有一个表(properties),有两列(id作为主键,data作为jsonb)。 数据结构为: { "ProductType": "ABC", "ProductName": "XYZ", "attributes": [ { "name&
{
"ProductType": "ABC",
"ProductName": "XYZ",
"attributes": [
{
"name": "Color",
"type": "STRING",
"value": "Silver"
},
{
"name": "Case",
"type": "STRING",
"value": "Shells"
},
...
]
}
我希望获取属性具有特定值的所有行,即返回Case='Shells'和/或Color='Red'的所有行
我尝试了以下方法,但无法应用两个条件,如Case='Shells'和Color='Silver'。
当单个属性的名称和值与条件匹配时,我可以获取行,但我不知道如何使其适用于多个属性
编辑1: 我可以使用以下查询获得结果:
WITH properties AS (
select *
from (
values
(1, '{"ProductType": "ABC","ProductName": "XYZ","attributes": [{"name": "Color","type": "STRING","value": "Silver"},{"name": "Case","type": "STRING","value": "Shells"}]}'::jsonb),
(2, '{"ProductType": "ABC","ProductName": "XYZ","attributes": [{"name": "Color","type": "STRING","value": "Red"},{"name": "Case","type": "STRING","value": "Shells"}]}'::jsonb)
) s(id, data)
)
select
*
from (
SELECT
id,
jsonb_object_agg(attr ->> 'name', attr -> 'value') as aggr
FROM properties m,
jsonb_array_elements(data -> 'attributes') as attr
GROUP BY id
) a
where aggr ->> 'Color' = 'Red' and aggr ->> 'Case' LIKE 'Sh%'
我可能有数百万条这样的记录,所以我想我现在唯一关心的是这是否有效,如果没有,还有更好的方法吗?
问题是,jsonb\u array\u elements()
将两个相关值移动到不同的记录中。但是,此调用对于获取值是必需的。因此,您需要在能够读取值之后重新聚合这些值。这将使以相关方式检查它们成为可能
这可以通过使用jsonb\u object\u agg()
聚合函数来实现。这里的诀窍是,我们创建一个具有属性的对象,如“name”:“value”
。这样,我们就可以使用@>
操作符轻松地检查JSON对象中是否存在所有必需的属性
关于“编辑1” 您可以这样做:
SELECT
*
FROM (
SELECT
id,
jsonb_object_agg(attr ->> 'name', attr -> 'value') as obj
FROM properties m,
jsonb_array_elements(data -> 'attributes') as attr
GROUP BY id
) s
WHERE obj ->> 'Color' = 'Silver'
AND obj ->> 'Case' LIKE 'Sh%'
HAVING
子句中使用jsonb\u object\u agg()。我想您需要检查哪种方式在您的情况下更有效:
SELECT
id
FROM properties m,
jsonb_array_elements(data -> 'attributes') as attr
GROUP BY id
HAVING
jsonb_object_agg(attr ->> 'name', attr -> 'value') ->> 'Color' = 'Silver'
AND
jsonb_object_agg(attr ->> 'name', attr -> 'value') ->> 'Case' LIKE 'Sh%'
是否可以对整数值应用类似“>=”的比较运算符或类似“like”、“EXISTS”的逻辑运算符?我是新来的,但我不会让任何人被绞死,我保证:我不太确定你想要实现什么。请编辑您的问题并显示更新的用例。关于效率有什么想法吗?答案补充道
SELECT
id
FROM properties m,
jsonb_array_elements(data -> 'attributes') as attr
GROUP BY id
HAVING
jsonb_object_agg(attr ->> 'name', attr -> 'value') ->> 'Color' = 'Silver'
AND
jsonb_object_agg(attr ->> 'name', attr -> 'value') ->> 'Case' LIKE 'Sh%'