postgresql - Postgres - 如何对 JSONB 字段执行 LIKE 查询?
问题描述
我有一个名为 的 jsonb 字段passengers
,其结构如下:
请注意,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 的名称字段执行查询?例如,选择与名称字段匹配的所有行Prof
?
这是我的初步尝试:
SELECT passengers from opportunities
WHERE 'passengers->adults' != NULL
AND 'passengers->adults->persons->name' LIKE '%Prof';
这将返回 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'
->
运算符返回一个值,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,您将需要一个子查询来取消嵌套数组元素(并因此迭代每个元素)。
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 路径表达式:
SELECT passengers
from opportunities
WHERE passengers @? '$.adults.persons[*] ? (@.name like_regex "Prof.*")'
推荐阅读
- python - 在 youtube API、python 中处理社区标记的视频
- java - 仅使用公钥 (OpenSAML) 的 Java 签名数据
- ios - 函数只在函数中更改全局变量,而不是在类中
- python - Scrapy shell - 用于从表中获取信息的正确 xpath 选择器?
- sorting - CUDA:thrust::sort_by_key 在内核中不起作用,但thrust::sort 可以
- python - 如何在 html 中添加加载更多按钮
- python - PyParse - 如果不匹配返回特定语句
- php - post isset($_POST['next'] 在提交/刷新页面后没有设置。需要按两次才能设置如何解决?
- python - Python/Pandas 按 Id 查找并匹配列值并返回结果
- java - 在java中将值保存到文件(例如yml)