使用 PostgreSQL 进行全文搜索

Tom*_*mmy 5 postgresql full-text-search postgresql-9.2

我有一个包含这些行的表:

Stickers
------------------------------------------------------
ID | Title                 |Keywords (ts_vector)
------------------------------------------------------
01 | Sticker Case 580H     |'580h':3 'cas':2 'stick':1
02 | Sticker Case 580L     |'580l':3 'cas':2 'stick':1
03 | Sticker Case 580      |'580':3 'cas':2 'stick':1
04 | Sticker Case Plus 3000|'3000':4 'cas':2 'plus':3 'stick':1
Run Code Online (Sandbox Code Playgroud)

好吧,当我使用这个脚本进行搜索时,只返回第 03 行,我如何返回第 01 和 02 行?

SELECT
*
FROM
stickers
WHERE
keywords @@@ to_tsquery('case & 580');
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 9

除了@swasheck 已经解释过的内容之外,将LIKE( ~~) 和ILIKE( ~~*)三元组 GiST 或 GIN 索引结合使用,您可能会获得更好的性能。您必须为此安装附加模块pg_trgm。在这些相关问题下查找详细信息:

Trigram 索引也可用于基本的正则表达式匹配 ( ~),但LIKE通常更快。

创建一个索引,如:

CREATE INDEX stickers_title_gin_trgm_idx ON stickers
USING gin (title gin_trgm_ops);
Run Code Online (Sandbox Code Playgroud)

那么这应该非常快:

SELECT *
FROM   stickers
WHERE  title ~~* '%case 580%';
Run Code Online (Sandbox Code Playgroud)

或者(从你的问题中不清楚):

SELECT *
FROM   stickers
WHERE  title ~~* '%case%'
AND    title ~~  '%580%';
Run Code Online (Sandbox Code Playgroud)


swa*_*eck 6

这并不是全文搜索的真正用例,因为全文依赖于对文本进行词干提取并将块解析为标记。从 中可以看出keywords,'580h' 被解析为它自己的词,因为没有任何语言中的 '580' 是 '580h' 的“词干”。使用正则表达式匹配可能会更好。

这是我为您准备的查询:

SELECT id, title 
  FROM stickers WHERE
    (title ~* '580')
      AND
    (title ~* 'case')
ORDER BY id
Run Code Online (Sandbox Code Playgroud)