如何对 hstore/jsonb 列的键执行模式匹配查询?
How to perform a pattern matching query on the keys of a hstore/jsonb column?
我正在尝试对 Postgresql 数据库的 hstore 列执行模式匹配 table。
这是我尝试过的:
SELECT
*
FROM
products
WHERE
'iphone8' LIKE ANY(AVALS(available_devices))
不过,ANY
运算符好像只支持<
、<=
、<>
等
我也试过这个:
SELECT
*
FROM
products
WHERE
ANY(AVALS(available_devices)) LIKE 'iphone8'
但随后会引发 SyntaxError。
那么,我可以使用 WHERE
子句进行查询吗?我在该子句中传递了一个参数,查询的结果是包含通知 hstore_column 中与给定参数?
例如:
对于行
id | hstore_column
1 { country: 'brazil' }
2 { city: 'amsterdam' }
3 { state: 'new york' }
4 { count: 10 }
5 { counter: 'Irelia' }
我想执行带有参数 'count'
的 WHERE
,我希望结果为:
id | hstore_column
1 { country: 'brazil' }
4 { count: 10 }
5 { counter: 'Irelia' }
您可以使用 jsonb_object_keys
将键变成一列。然后匹配密钥。
例如,这是我的测试数据。
select * from test;
id | stuff
----+---------------------------------------------
1 | {"country": "brazil"}
2 | {"city": "amsterdam"}
3 | {"count": 10}
4 | {"pearl": "jam", "counting": "crows"}
5 | {"count": "chocula", "count down": "final"}
然后我们可以使用jsonb_object_keys
将每个键变成它自己的行。
select id, stuff, jsonb_object_keys(stuff) as key
from test;
id | stuff | key
----+---------------------------------------------+------------
1 | {"country": "brazil"} | country
2 | {"city": "amsterdam"} | city
3 | {"count": 10} | count
4 | {"pearl": "jam", "counting": "crows"} | pearl
4 | {"pearl": "jam", "counting": "crows"} | counting
5 | {"count": "chocula", "count down": "final"} | count
5 | {"count": "chocula", "count down": "final"} | count down
这可以在子 select 中使用以获得每个匹配的 key/value 对。
select id, stuff, key, stuff->key as value
from (
select id, stuff, jsonb_object_keys(stuff) as key
from test
) pairs
where key like 'count%';
id | stuff | key | value
----+---------------------------------------------+------------+-----------
1 | {"country": "brazil"} | country | "brazil"
3 | {"count": 10} | count | 10
4 | {"pearl": "jam", "counting": "crows"} | counting | "crows"
5 | {"count": "chocula", "count down": "final"} | count | "chocula"
5 | {"count": "chocula", "count down": "final"} | count down | "final"
或者我们可以使用 distinct
来获取匹配的行。
select distinct id, stuff
from (
select id, stuff, jsonb_object_keys(stuff) as key
from test
) pairs
where key like 'count%';
id | stuff
----+---------------------------------------------
1 | {"country": "brazil"}
3 | {"count": 10}
4 | {"pearl": "jam", "counting": "crows"}
5 | {"count": "chocula", "count down": "final"}
注意:必须搜索键表示您的数据结构可能需要重新考虑。传统的 key/value table 可能效果更好。这些值仍然可以是 jsonb。设置多了一点,但查询更简单,索引也更容易。
create table attribute_group (
id bigserial primary key
);
create table test (
id bigserial primary key,
attribute_group_id bigint
references attribute_group(id)
on delete cascade
);
create table attributes (
attribute_group_id bigint
references attribute_group(id) not null,
key text not null,
value jsonb not null
);
select test.id, attrs.key, attrs.value
from test
join attributes attrs on attrs.attribute_group_id = test.attribute_group_id
where attrs.key like 'count%';
我正在尝试对 Postgresql 数据库的 hstore 列执行模式匹配 table。
这是我尝试过的:
SELECT
*
FROM
products
WHERE
'iphone8' LIKE ANY(AVALS(available_devices))
不过,ANY
运算符好像只支持<
、<=
、<>
等
我也试过这个:
SELECT
*
FROM
products
WHERE
ANY(AVALS(available_devices)) LIKE 'iphone8'
但随后会引发 SyntaxError。
那么,我可以使用 WHERE
子句进行查询吗?我在该子句中传递了一个参数,查询的结果是包含通知 hstore_column 中与给定参数?
例如: 对于行
id | hstore_column
1 { country: 'brazil' }
2 { city: 'amsterdam' }
3 { state: 'new york' }
4 { count: 10 }
5 { counter: 'Irelia' }
我想执行带有参数 'count'
的 WHERE
,我希望结果为:
id | hstore_column
1 { country: 'brazil' }
4 { count: 10 }
5 { counter: 'Irelia' }
您可以使用 jsonb_object_keys
将键变成一列。然后匹配密钥。
例如,这是我的测试数据。
select * from test;
id | stuff
----+---------------------------------------------
1 | {"country": "brazil"}
2 | {"city": "amsterdam"}
3 | {"count": 10}
4 | {"pearl": "jam", "counting": "crows"}
5 | {"count": "chocula", "count down": "final"}
然后我们可以使用jsonb_object_keys
将每个键变成它自己的行。
select id, stuff, jsonb_object_keys(stuff) as key
from test;
id | stuff | key
----+---------------------------------------------+------------
1 | {"country": "brazil"} | country
2 | {"city": "amsterdam"} | city
3 | {"count": 10} | count
4 | {"pearl": "jam", "counting": "crows"} | pearl
4 | {"pearl": "jam", "counting": "crows"} | counting
5 | {"count": "chocula", "count down": "final"} | count
5 | {"count": "chocula", "count down": "final"} | count down
这可以在子 select 中使用以获得每个匹配的 key/value 对。
select id, stuff, key, stuff->key as value
from (
select id, stuff, jsonb_object_keys(stuff) as key
from test
) pairs
where key like 'count%';
id | stuff | key | value
----+---------------------------------------------+------------+-----------
1 | {"country": "brazil"} | country | "brazil"
3 | {"count": 10} | count | 10
4 | {"pearl": "jam", "counting": "crows"} | counting | "crows"
5 | {"count": "chocula", "count down": "final"} | count | "chocula"
5 | {"count": "chocula", "count down": "final"} | count down | "final"
或者我们可以使用 distinct
来获取匹配的行。
select distinct id, stuff
from (
select id, stuff, jsonb_object_keys(stuff) as key
from test
) pairs
where key like 'count%';
id | stuff
----+---------------------------------------------
1 | {"country": "brazil"}
3 | {"count": 10}
4 | {"pearl": "jam", "counting": "crows"}
5 | {"count": "chocula", "count down": "final"}
注意:必须搜索键表示您的数据结构可能需要重新考虑。传统的 key/value table 可能效果更好。这些值仍然可以是 jsonb。设置多了一点,但查询更简单,索引也更容易。
create table attribute_group (
id bigserial primary key
);
create table test (
id bigserial primary key,
attribute_group_id bigint
references attribute_group(id)
on delete cascade
);
create table attributes (
attribute_group_id bigint
references attribute_group(id) not null,
key text not null,
value jsonb not null
);
select test.id, attrs.key, attrs.value
from test
join attributes attrs on attrs.attribute_group_id = test.attribute_group_id
where attrs.key like 'count%';