使用 Postgres 全文搜索来搜索完全匹配的最佳方法是什么?
What is the best way to search for an exact match using Postgres full-text search?
我有一个包含大约 150 万条记录的 Postgres 数据库。在我的 Ruby on Rails 应用程序中,我需要搜索 statement_text
字段(可以包含 1 到数百个单词)。
我的问题:我知道我可以使用 pgSearch
gem 来创建像 search_all_words
或 search_any_words
这样的范围,但我不确定什么是最有效的确保在结果集中只返回 完全匹配 的记录的方法。
也就是说,如果我搜索 "Pope Francis",我希望它只找到连续且顺序相同的这两个词(而不是 "The pope is named Francis")。
到目前为止,我只是将 GIN 索引与 ILIKE
结合起来进行精确匹配搜索。但是鉴于 GIN 索引在每条记录中基本上都按 storing the exact position of a word 工作,难道不应该有更有效的(非 ILIKE
)方法来确保搜索词与字段完全匹配吗?
一般来说,全文需要根据所使用的语言词典进行词干提取,因此通过使用全文搜索,您可以使用 ts_rank()
功能而不使用 词干提取 'simple'
字典以确定您正在搜索的短语的相关性。
WITH t(v) AS ( VALUES
('Test sentence with Pope Francis'),
('Test Francis sentence with Pope '),
('The pope is named Francis')
)
SELECT v,ts_rank(tsv,q) as rank
FROM t,
to_tsvector('simple',v) as tsv,
plainto_tsquery('simple','Pope Francis') AS q;
结果:
v | rank
----------------------------------+-----------
Test sentence with Pope Francis | 0.0991032
Test Francis sentence with Pope | 0.0973585
The pope is named Francis | 0.0973585
(3 rows)
无需全文搜索,您可以使用 pg_trgm
extension. Example is here.
实现更快的 ILIKE
模式匹配
我有一个包含大约 150 万条记录的 Postgres 数据库。在我的 Ruby on Rails 应用程序中,我需要搜索 statement_text
字段(可以包含 1 到数百个单词)。
我的问题:我知道我可以使用 pgSearch
gem 来创建像 search_all_words
或 search_any_words
这样的范围,但我不确定什么是最有效的确保在结果集中只返回 完全匹配 的记录的方法。
也就是说,如果我搜索 "Pope Francis",我希望它只找到连续且顺序相同的这两个词(而不是 "The pope is named Francis")。
到目前为止,我只是将 GIN 索引与 ILIKE
结合起来进行精确匹配搜索。但是鉴于 GIN 索引在每条记录中基本上都按 storing the exact position of a word 工作,难道不应该有更有效的(非 ILIKE
)方法来确保搜索词与字段完全匹配吗?
一般来说,全文需要根据所使用的语言词典进行词干提取,因此通过使用全文搜索,您可以使用 ts_rank()
功能而不使用 词干提取 'simple'
字典以确定您正在搜索的短语的相关性。
WITH t(v) AS ( VALUES
('Test sentence with Pope Francis'),
('Test Francis sentence with Pope '),
('The pope is named Francis')
)
SELECT v,ts_rank(tsv,q) as rank
FROM t,
to_tsvector('simple',v) as tsv,
plainto_tsquery('simple','Pope Francis') AS q;
结果:
v | rank
----------------------------------+-----------
Test sentence with Pope Francis | 0.0991032
Test Francis sentence with Pope | 0.0973585
The pope is named Francis | 0.0973585
(3 rows)
无需全文搜索,您可以使用 pg_trgm
extension. Example is here.
ILIKE
模式匹配