【问题标题】:Postgres Full Text Search on Array Column数组列上的 Postgres 全文搜索
【发布时间】: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

【问题讨论】:

    标签: postgresql


    【解决方案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;
    猜你喜欢
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多