我有一张表格:
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 }]
在文字部分中按字词查找文档需要哪些查询?
答案 0 :(得分:1)
有很复杂的方法可以实现您的目标,但我会提倡更简单的方法,例如将此正文列视为文本并使用普通的like
做这个工作:
SELECT * FROM public.items WHERE body::TEXT LIKE '%child%'
OR
SELECT * FROM public.items WHERE body::TEXT SIMILAR TO '%child%'
如果您不希望它区分大小写,请在比较它们之前转换它们,例如使用LOWER
或UPPER
(请参阅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"}