Match a phrase ending in a prefix with full text search

后端 未结 4 998
北恋
北恋 2020-12-31 14:36

I\'m looking for a way to emulate something like SELECT * FROM table WHERE attr LIKE \'%text%\' using a tsvector in PostgreSQL.

I\'ve created a tsvector

4条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-12-31 15:14

    Postgres 9.6 introduces phrase search capabilities for full text search. So this works now:

    SELECT title
    FROM  tbl
    WHERE title_tsv @@ to_tsquery('zend <-> fram:*');

    <-> being the FOLLOWED BY operator.

    It finds 'foo Zend framework bar' or 'Zend frames', but not 'foo Zend has no framework bar'.

    Quoting the release notes for Postgres 9.6:

    A phrase-search query can be specified in tsquery input using the new operators <-> and <N>. The former means that the lexemes before and after it must appear adjacent to each other in that order. The latter means they must be exactly N lexemes apart.

    For best performance support the query with a GIN index:

    CREATE INDEX tbl_title_tsv_idx ON tbl USING GIN (title_tsv);
    

    Or don't store title_tsv in the table at all (bloating it and complicating writes). You can use an expression index instead:

    CREATE INDEX tbl_title_tsv_idx ON tbl USING GIN (to_tsvector('english', title));
    

    You need to specify the text search configuration (often language-specific) to make the expression immutable. And adapt the query accordingly:

    ...
    WHERE to_tsvector('english', title) @@ to_tsquery('english', 'zend <-> fram:*');
    

提交回复
热议问题