Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql JSONB数组包含like OR和and运算符_Sql_Json_Postgresql_Jsonb - Fatal编程技术网

Sql JSONB数组包含like OR和and运算符

Sql JSONB数组包含like OR和and运算符,sql,json,postgresql,jsonb,Sql,Json,Postgresql,Jsonb,考虑一个表temp(jsondatajsonb) Postgres提供了一种使用 SELECT jsondata FROM temp WHERE (jsondata->'properties'->'home') ? 'football' 但是,我们不能对数组包含使用LIKE运算符。在数组中获得LIKE的一种方法是使用- SELECT jsondata FROM temp,jsonb_array_elements_text(temp.jsondata->'properti

考虑一个表
temp(jsondatajsonb)

Postgres提供了一种使用

SELECT jsondata 
FROM temp 
WHERE (jsondata->'properties'->'home') ? 'football'
但是,我们不能对数组包含使用LIKE运算符。在数组中获得LIKE的一种方法是使用-

SELECT jsondata 
FROM temp,jsonb_array_elements_text(temp.jsondata->'properties'->'home') 
WHERE value like '%foot%'
或类似的操作可以通过使用-

SELECT DISTINCT jsondata 
FROM temp,jsonb_array_elements_text(temp.jsondata->'properties'->'home') 
WHERE value like '%foot%' OR value like 'stad%'

但是,我无法在JSONB数组中使用LIKE运算符执行和操作

我有以下内容,但有点烦琐。也许有更好的方法,但我认为这是可行的

其思想是找到匹配的JSON数组条目,然后收集结果。在连接条件中,我们检查“matches”数组是否具有预期的条目数

CREATE TABLE temp (jsondata jsonb);

INSERT INTO temp VALUES ('{"properties":{"home":["football","stadium",16]}}');

SELECT jsondata FROM temp t
INNER JOIN LATERAL (
    SELECT array_agg(value) AS matches
    FROM jsonb_array_elements_text(t.jsondata->'properties'->'home')
    WHERE value LIKE '%foo%' OR value LIKE '%sta%'
    LIMIT 1        
) l ON array_length(matches, 1) = 2;

                           jsondata                        
-------------------------------------------------------
 {"properties": {"home": ["football", "stadium", 16]}}
(1 row)

使用
jsonb\u array\u elements()
取消对数组的测试后,可以检查满足其中一个条件的
值,并按原始行分组求和,例如:

drop table if exists temp;
create table temp(id serial primary key, jsondata jsonb);
insert into temp (jsondata) values
    ('{"properties":{"home":["football","stadium","16"]}}'),
    ('{"properties":{"home":["football","player","16"]}}'),
    ('{"properties":{"home":["soccer","stadium","16"]}}');

select jsondata
from temp 
cross join jsonb_array_elements_text(temp.jsondata->'properties'->'home') 
group by jsondata 
-- or better:
-- group by id
having sum((value like '%foot%' or value like 'stad%')::int) = 2

                        jsondata                         
---------------------------------------------------------
 {"properties": {"home": ["football", "stadium", "16"]}}
(1 row)

更新。对于大型数据集,上面的查询可能很昂贵。有一个简化但更快的解决方案。您可以将数组强制转换为文本并对其应用
like
,例如:

select jsondata
from temp 
where jsondata->'properties'->>'home' like all('{%foot%, %stad%}');

                        jsondata                         
---------------------------------------------------------
 {"properties": {"home": ["football", "stadium", "16"]}}
(1 row) 

我将把数组转换成文本。然后,您可以使用每个字符串运算符搜索关键字

缺点:因为它是一个数组,所以文本包含大括号和逗号等字符。因此,搜索具有特定开头的关键字并不是那么简单(
ABC%
):您必须始终像
%ABC%

SELECT jsondata
FROM (
    SELECT 
        jsondata, 
        jsondata->'properties'->>'home' as a
    FROM 
        temp
)s
WHERE 
    a LIKE '%stad%' AND a LIKE '%foot%'

你确定你有任何包含“foot”并以“stad”开头的“home”值吗?json看起来像-{“properties”:{“home”:[“football”,“stadium”,“16”]}我想在home数组上执行-%foot%和%stad%这样的操作,但是当你使用
正确时,你没有一个值同时包含这两个值。这就是我无法执行此操作的原因。我刚试过这个选择。但是,如果有更好的方法不使用价值,那也会更好。我想要实现的就是用OR和and操作在JSONB数组上执行LIKE操作。但是,这涉及到连接和分组,这是一项繁重的操作。所以,我更喜欢不涉及这个手术的东西。只需使用LIKE和and运算符。