PostgreSQL JSONB按字词查找文档

时间:2018-04-11 21:09:25

标签: sql postgresql jsonb

我有一张表格:

                          Table "public.items"
     Column      |           Type           |         Modifiers         
-----------------+--------------------------+---------------------------
 item_id         | character varying        | not null
 content         | character varying        | 
 tags            | jsonb                    | 
 body            | jsonb                    | 

正文字段包含以下数据:

[{"text": "As a child home ..."}, 
{"text": "Great post. Watch this }]

文字部分中按字词查找文档需要哪些查询?

2 个答案:

答案 0 :(得分:1)

有很复杂的方法可以实现您的目标,但我会提倡更简单的方法,例如将此正文列视为文本并使用普通的like做这个工作:

SELECT * FROM public.items WHERE body::TEXT LIKE '%child%'

OR

SELECT * FROM public.items WHERE body::TEXT SIMILAR TO '%child%'

如果您不希望它区分大小写,请在比较它们之前转换它们,例如使用LOWERUPPER(请参阅documentation):

SELECT * FROM items WHERE LOWER(body::TEXT) LIKE LOWER('%CHILD%')

编辑:正如Dan在评论中所建议的,ILIKE是处理不区分大小写查询的另一种优雅方式:

SELECT * FROM items WHERE body::TEXT ILIKE '%CHILD%'

答案 1 :(得分:1)

您可以使用jsonb函数进行搜索。 让我们说你有这个:

item_id | body
--------+---------------------------------------------------------------
1       | [{"text":"aSdf aSdf"},{"text":"12 41f"},{"text":"1 31s sf"}]
2       | [{"text":"31fa3"},{"text":"3f43f"}]
3       | [{"text":"l8412"},{"text":"52%$3d1f"},{"text":"agasd as3"}]
4       | [{"text":"i8i23"}]

您可以使用以下方法搜索jsonb中的每个元素:

SELECT * FROM (SELECT t.id,elem.*
FROM public.items t,jsonb_array_elements(t.body) AS elem)json_vals
WHERE value->>'text' ILIKE '%s%'

这将返回下一个结果,因为查询使用ILIKE

item_id | value
--------+----------------------
1       | {"text":"aSdf aSdf"}
1       | {"text":"1 31s sf"}
3       | {"text":"agasd as3"}

如果您只需要该ID,则可以更改*查询中的item_id并使用DISTINCT。但是使用此查询,您可以访问记录中的每个JSON,而无需将其转换为text

注意:如果您只是查询SELECT t.id,elem.* FROM public.items t,jsonb_array_elements(t.body) AS elem,您会获得连续的所有元素:

itme_id | value
--------+--------------------
1       | {"text":"aSdf aSdf"}
1       | {"text":"12 41f"}
1       | {"text":"1 31s sf"}
2       | {"text":"31fa3"}
2       | {"text":"3f43f"}
3       | {"text":"l8412"}
3       | {"text":"52%$3d1f"}
3       | {"text":"agasd as3"}
4       | {"text":"i8i23"}