如何在 JSON Postgres 数据类型列中搜索特定字符串?
Posted
技术标签:
【中文标题】如何在 JSON Postgres 数据类型列中搜索特定字符串?【英文标题】:How do I search for a specific string in a JSON Postgres data type column? 【发布时间】:2018-02-01 14:53:47 【问题描述】:我在名为 reports
的表中有一个名为 params
的列,其中包含 JSON。
我需要在 JSON 数组的任意位置找到包含文本“authVar”的行。我不知道文本可能出现的路径或级别。
我只想使用标准的类似运算符搜索 JSON。
类似:
SELECT * FROM reports
WHERE params LIKE '%authVar%'
我已经搜索和谷歌搜索并阅读了 Postgres 文档。我不太了解 JSON 数据类型,并且认为我遗漏了一些简单的东西。
JSON 看起来像这样。
[
"tileId":18811,
"Params":
"data":[
"name":"Week Ending",
"color":"#27B5E1",
"report":"report1",
"locations":
"c1":0,
"c2":0,
"r1":"authVar",
"r2":66
]
]
【问题讨论】:
【参考方案1】:在 Postgres 11 或更早的版本中,可以递归遍历未知的 json 结构,但这会相当复杂且成本高昂。我会提出 brute force 应该很好用的方法:
select *
from reports
where params::text like '%authVar%';
-- or
-- where params::text like '%"authVar"%';
-- if you are looking for the exact value
查询速度非常快,但如果搜索的字符串是其中一个键的一部分,则可能会返回意外的额外行。
在 Postgres 12+ 中,JSONB 中的递归搜索非常适合 jsonpath
的新功能。
查找包含authVar的字符串值:
select *
from reports
where jsonb_path_exists(params, '$.** ? (@.type() == "string" && @ like_regex "authVar")')
json 路径:
$.** find any value at any level (recursive processing)
? where
@.type() == "string" value is string
&& and
@ like_regex "authVar" value contains 'authVar'
或者找到确切的值:
select *
from reports
where jsonb_path_exists(params, '$.** ? (@ == "authVar")')
阅读文档:
The SQL/JSON Path Language jsonpath Type【讨论】:
递归遍历有什么好处? 本教程详细讲解“params::text”:postgresqltutorial.com/postgresql-cast @CaleSweeney - 当我们搜索与某个键相同的属性时,这个简单的解决方案将失败。 有没有办法使用带有多个参数且不区分大小写的“jsonb_path_exists”? @ersu - 是的,请阅读文档中的9.15.2.2. Regular Expressions。以上是关于如何在 JSON Postgres 数据类型列中搜索特定字符串?的主要内容,如果未能解决你的问题,请参考以下文章
在 slick、scala 中处理 Postgres json 数据类型
使用 Spring / JPA 写入 Postgres 数据库的 JSON 列
在Rails中为Postgres JSON列设置默认值< 4