我有一个包含以下(相关)字段的articles
表
CREATE TABLE
IF NOT EXISTS articles (
...
...
title TEXT NOT NULL,
content JSONB NOT NULL,
search_index TSVECTOR NOT NULL,
...
...
);
带有search_index
上的索引
CREATE INDEX articles_search_index ON articles USING gin(search_index);
而且我希望能够搜索title
和content
,而没有任何特定的优先级。
我想把整个content
数据当作一个文本块,而不实际改变它的结构。
我希望能奏效的是:
CREATE TRIGGER articles_search_index_update BEFORE INSERT
OR
UPDATE
ON articles FOR EACH ROW EXECUTE FUNCTION
tsvector_update_trigger
(search_index,
'pg_catalog.english',
title,
content
);
错误-column \"content\" is not of a character type
,这是可以理解的,因为tsvector_update_trigger
需要文本列。
该函数中是否可以包含jsonb
内容?
2条答案
按热度按时间xpszyzbs1#
您可以使用
jsonb_to_tsvector()
生成的列。由于您还希望索引标题,因此需要将content
列与包含标题的JSON值连接起来。大致如下:
请注意,您不能使用
jsonb_build_object()
,因为不幸的是,它没有标记为“不可变”,但jsonb_object()
标记为“不可变”。如果存储在
content
列中的JSON可以包含顶级键title
,则需要使用不同的键,可能是jsonb_object(array['__title', title])
。我可以看到的一个优点(除了不必管理触发器之外)是,这只索引实际的JSON * 值 * 而不是键,因此我希望这会产生更准确的搜索结果。
xdnvmnnf2#
你可以通过在更新触发器中使用
content::text
而不是content
来将整个json转换为一个字符串,但是json的所有括号,键和逗号也会被抛出,这可能会有问题。如果内容总是包含相同的简单属性,那么手动提取(相关的)属性,将它们转换为文本,并将它们连接在一起会更简洁。