Postgres - 如何对 JSONB 字段执行 LIKE 查询?
Postgres - How to perform a LIKE query on a JSONB field?
我有一个名为 passengers
的 jsonb 字段,其结构如下:
注意persons是一个数组
{
"adults": {
"count": 2,
"persons": [
{
"age": 45,
"name": "Prof. Kyleigh Walsh II",
"birth_date": "01-01-1975"
},
{
"age": 42,
"name": "Milford Wiza",
"birth_date": "02-02-1978"
}
]
}
}
我如何对该 JSONB 的名称字段执行查询?例如,select 匹配名称字段 Prof
?
的所有行
这是我的初步尝试:
SELECT passengers from opportunities
WHERE 'passengers->adults' != NULL
AND 'passengers->adults->persons->name' LIKE '%Prof';
这 returns 0 行,但如您所见,我有一行名称为 Prof. Kyleigh Walsh II
这:'passengers->adults->persons->name' LIKE '%Prof';
检查字符串 'passengers->adults->persons->name'
是否以 Prof
结尾。
JSON 运算符的每个键都需要是一个单独的元素,列名不得用单引号引起来。所以 'passengers->adults->persons->name'
需要 passengers -> 'adults' -> 'persons' -> 'name'
->
运算符returns一个jsonb
值,你想要一个text
值,所以最后一个运算符应该是->>
另外!= null
不行,需要用is not null
.
SELECT passengers
from opportunities
WHERE passengers -> 'adults' is not NULL
AND passengers -> 'adults' -> 'persons' ->> 'name' LIKE 'Prof%';
is not null
条件并不是真正必要的,因为第二个条件暗示了这一点。第二个条件可以简化为:
SELECT passengers
from opportunities
WHERE passengers #>> '{adults,persons,name}' LIKE 'Prof%';
但由于 persons
是一个数组,上面的方法行不通,您需要使用不同的方法。
对于 Postgres 9.6,您将需要一个 sub-query 来解除数组元素的嵌套(从而遍历每个元素)。
SELECT passengers
from opportunities
WHERE exists (select *
from jsonb_array_elements(passengers -> 'adults' -> 'persons') as p(person)
where p.person ->> 'name' LIKE 'Prof%');
要用LIKE匹配开头的字符串,通配符需要在末尾。 '%Prof'
会匹配 'Some Prof'
但不会匹配 'Prof. Kyleigh Walsh II'
对于 Postgres 12,您可以使用 SQL/JSON Path 表达式:
SELECT passengers
from opportunities
WHERE passengers @? '$.adults.persons[*] ? (@.name like_regex "Prof.*")'
我有一个名为 passengers
的 jsonb 字段,其结构如下:
注意persons是一个数组
{
"adults": {
"count": 2,
"persons": [
{
"age": 45,
"name": "Prof. Kyleigh Walsh II",
"birth_date": "01-01-1975"
},
{
"age": 42,
"name": "Milford Wiza",
"birth_date": "02-02-1978"
}
]
}
}
我如何对该 JSONB 的名称字段执行查询?例如,select 匹配名称字段 Prof
?
这是我的初步尝试:
SELECT passengers from opportunities
WHERE 'passengers->adults' != NULL
AND 'passengers->adults->persons->name' LIKE '%Prof';
这 returns 0 行,但如您所见,我有一行名称为 Prof. Kyleigh Walsh II
这:'passengers->adults->persons->name' LIKE '%Prof';
检查字符串 'passengers->adults->persons->name'
是否以 Prof
结尾。
JSON 运算符的每个键都需要是一个单独的元素,列名不得用单引号引起来。所以 'passengers->adults->persons->name'
需要 passengers -> 'adults' -> 'persons' -> 'name'
->
运算符returns一个jsonb
值,你想要一个text
值,所以最后一个运算符应该是->>
另外!= null
不行,需要用is not null
.
SELECT passengers
from opportunities
WHERE passengers -> 'adults' is not NULL
AND passengers -> 'adults' -> 'persons' ->> 'name' LIKE 'Prof%';
is not null
条件并不是真正必要的,因为第二个条件暗示了这一点。第二个条件可以简化为:
SELECT passengers
from opportunities
WHERE passengers #>> '{adults,persons,name}' LIKE 'Prof%';
但由于 persons
是一个数组,上面的方法行不通,您需要使用不同的方法。
对于 Postgres 9.6,您将需要一个 sub-query 来解除数组元素的嵌套(从而遍历每个元素)。
SELECT passengers
from opportunities
WHERE exists (select *
from jsonb_array_elements(passengers -> 'adults' -> 'persons') as p(person)
where p.person ->> 'name' LIKE 'Prof%');
要用LIKE匹配开头的字符串,通配符需要在末尾。 '%Prof'
会匹配 'Some Prof'
但不会匹配 'Prof. Kyleigh Walsh II'
对于 Postgres 12,您可以使用 SQL/JSON Path 表达式:
SELECT passengers
from opportunities
WHERE passengers @? '$.adults.persons[*] ? (@.name like_regex "Prof.*")'