【发布时间】:2021-05-06 16:28:24
【问题描述】:
我正在尝试编写一个 sql 查询来查找表中与提供的 json 数组的任何值匹配的行。
更具体地说,我有以下 db 表:
CREATE TABLE mytable (
name text,
id SERIAL PRIMARY KEY,
config json,
matching boolean
);
INSERT INTO "mytable"(
"name", "id", "config", "matching"
)
VALUES
(
E 'Name 1', 50,
E '{"employees":[1,7],"industries":["1","3","4","13","14","16"],"levels":["1110","1111","1112","1113","1114"],"revenue":[0,5],"states":["AK","Al","AR","AZ","CA","CO","CT","DC","DE","FL","GA","HI","IA","ID","IL"]}',
TRUE
),
(
E 'Name 2', 63,
E '{"employees":[3,5],"industries":["1"],"levels":["1110"],"revenue":[2,5],"states":["AK","AZ","CA","CO","HI","ID","MT","NM","NV","OR","UT","WA","WY"]}',
TRUE,
),
(
E 'Name 3', 56,
E '{"employees":[0,0],"industries":["14"],"levels":["1111"],"revenue":[7,7],"states":["AK","AZ","CA","CO","HI","ID","MT","NM","NV","OR","UT","WA","WY"]}',
TRUE,
),
(
E 'Name 4', 61,
E '{"employees":[3,8],"industries":["1"],"levels":["1110"],"revenue":[0,5],"states":["AK","AZ","CA","CO","HI","ID","WA","WY"]}',
FALSE
);
我需要使用给定的过滤参数对此表执行搜索查询。过滤参数基本对应config字段中的json键。它们来自客户端,看起来像这样:
{"employees": [1, 8], "industries": ["12", "5"]}
{"states": ["LA", "WA", "CA"], "levels": ["1100", "1100"], "employees": [3]}
给定这样的过滤器,我需要在我的表中找到包含所提供的每个过滤器键的相应过滤器键中的任何数组元素的行。
因此,给定过滤器{"employees": [1, 8], "industries": ["12", "5"]},查询必须返回所有行,其中(config 字段中的employees 键包含1 或8 AND 其中@987654329 @key in config 字段包含12 或5);
我需要从 javascript 代码中动态生成这样的查询,以便我可以通过添加/删除 AND 运算符的某个参数来包含/排除过滤。
到目前为止,我所拥有的是一个超级长时间运行的查询,它会在 config 字段中生成所有可能的数组元素组合,感觉非常错误:
select * from mytable
cross join lateral json_array_elements(config->'employees') as e1
cross join lateral json_array_elements(config->'states') as e2
cross join lateral json_array_elements(config->'levels') as e3
cross join lateral json_array_elements(config->'revenue') as e4;
我也尝试过这样做:
select * from mytable
where
matching = TRUE
and (config->'employees')::jsonb @> ANY(ARRAY ['[1, 7, 8]']::jsonb[])
and (config->'states')::jsonb @> ANY(ARRAY ['["AK", "AZ"]']::jsonb[])
and ........;
然而这并没有奏效,尽管看起来很有希望。
另外,我尝试过使用?| 运算符,但无济于事。
基本上,我需要的是:给定一个 json 字段中的数组键,检查该字段是否包含另一个数组中提供的任何值(这是我的过滤参数);我必须动态地为多个过滤参数执行此操作。
所以逻辑如下:
select all rows from the table
*where*
matching = TRUE
*and* config->key1 includes any of the keys from [5,6,8,7]
*and* config->key2 includes any of the keys from [8,6,2]
*and* so forth;
你能帮我实现这样一个 sql 查询吗?
或者也许这样的 sql 查询总是非常慢,最好在数据库级别之外进行这样的过滤?
【问题讨论】:
标签: sql postgresql plpgsql jsonb