数组列上的 Postgres 全文搜索
Posted
技术标签:
【中文标题】数组列上的 Postgres 全文搜索【英文标题】:Postgres Full Text Search on Array Column 【发布时间】:2015-04-15 01:11:36 【问题描述】:我有一个posts
,其中有一列tags
。我希望能够跨标签进行全文搜索。对于我使用过的VARCHAR
列:
CREATE INDEX posts_fts_idx ON posts USING gin(to_tsvector('english', coalesce(title, ''));
SELECT "posts".* FROM "posts" WHERE (to_tsvector('english', coalesce(title, '')) @@ (to_tsquery('english', 'ruby')));
但是,对于character varying[]
,函数to_tsvector
不存在。如何编写一个针对每个标签运行的查询(如果有任何单个标签匹配,则理想情况下匹配)?
注意:我发现转换为字符串 (array_to_string
) 非常容易,但如果可能的话,我想将每个单独的标签转换为 tsvector
。
【问题讨论】:
【参考方案1】:您可以使用 gin 为搜索选项索引不同的字符。试试这个:
CREATE INDEX idx_post_tag ON posts USING GIN(tags);
SELECT * FROM posts WHERE tags @> (ARRAY['search string'::character varying]);
这是需要精确匹配的时候。如果不需要完全匹配,您应该考虑将标签存储为文本列。更多地考虑这些“标签”的重要性。字符串数组类型缺乏文本索引、词干和变形支持,因此您将无法匹配诸如“Dancing”和“Dance”之类的词。
如果这不是一个选项,您可以使用不可变版本的 array_to_string 函数来规避这一点。您的查询将是:
CREATE INDEX posts_fts_idx ON posts USING gin(to_tsvector('english', immutable_array_to_string(tags, ' ')));
SELECT "posts".* FROM "posts" WHERE (to_tsvector('english', immutable_array_to_string(tags, ' ')) @@ (to_tsquery('english', 'ruby')));
【讨论】:
感谢您的回复,但这不会使用全文搜索。这需要完全匹配,并且不会考虑拼写和英语的相似性(即跳舞与跳舞)。 是的,我在我的问题中提到了这一点——我希望尝试将 tsvector 应用于数组的每个元素——而不是加入数组然后应用。问题是这将匹配标签之间的字符串。 这个immutable_array_to_string
函数来自哪里?
我找不到immutable_array_to_string
的任何文档
看起来像这样:CREATE OR REPLACE FUNCTION immutable_array_to_string(text[]) RETURNS text as $$ SELECT array_to_string($1, ','); $$ LANGUAGE sql IMMUTABLE;
以上是关于数组列上的 Postgres 全文搜索的主要内容,如果未能解决你的问题,请参考以下文章
使用 Postgres 全文搜索搜索完全匹配的最佳方法是啥?