在 postgresql 中使用 to_tsvector 和 to_tsquery 处理拼写错误
Handling typos with to_tsvector and to_tsquery in postgresql
我有一个带有这些字段的简单 table
最后两个字段用于索引一个为 tsvector 数据类型,另一个为文本数据类型。
我想查询姓名或身份证。我正在做这个
SELECT * FROM foo WHERE foo.searchtext @@ to_tsquery('1234 & abcd');
它工作正常,但现在我想删除拼写错误,例如,如果名称是 abcd,我输入 abbd,那么它应该得到所有可能的值。
我见过 pg_tgrm()
但它 does not 与整数或 tsvector
一起工作
我尝试使用其他选项 pg_tgrm()
就像我将索引存储在另一个字段 searchtextstring 中,类型为 text 和查询
select *
from foo
where searchtextstring % '123' and searchtextstring % 'abbd';
但我不认为这是有效的,而且这对打字错误不起作用。
那么如何处理 to_tsquery 的拼写错误?
谢谢
全文搜索仅忽略词干和大小写的差异,不会让您根据相似性查找匹配项。
pg_trgm
是要走的路。
我用这个样本table:
CREATE TABLE foo (id integer PRIMARY KEY, searchtextstring text);
INSERT INTO foo VALUES (1, 'something 0987');
INSERT INTO foo VALUES (2, 'abbd 1224');
CREATE INDEX ON foo USING gist (searchtextstring gist_trgm_ops);
这太小了,PostgreSQL 将始终使用顺序扫描,所以如果可能的话,让我们强制 PostgreSQL 使用索引(以便我们可以模拟更大的 table):
SET enable_seqscan = off;
现在查询:
EXPLAIN (COSTS off)
SELECT * FROM foo WHERE searchtextstring % '1234'
AND searchtextstring % 'abcd';
QUERY PLAN
--------------------------------------------------------
Index Scan using foo_searchtextstring_idx on foo
Index Cond: ((searchtextstring % '1234'::text)
AND (searchtextstring % 'abcd'::text))
(2 rows)
索引使用的很好,单次索引扫描!
但是查询returns没有行:
SELECT * FROM foo WHERE searchtextstring % '1234'
AND searchtextstring % 'abcd';
id | searchtextstring
----+------------------
(0 rows)
不是因为“不行”,而是词不够相似。别忘了一个四字的字里没有那么多八卦,换一个字母就没那么相似了。这并不奇怪,对吧?
所以我们必须降低相似度阈值才能得到结果;
SET pg_trgm.similarity_threshold = 0.1;
SELECT * FROM foo WHERE searchtextstring % '1234'
AND searchtextstring % 'abcd';
id | searchtextstring
----+------------------
2 | abbd 1224
(1 row)
我有一个带有这些字段的简单 table
最后两个字段用于索引一个为 tsvector 数据类型,另一个为文本数据类型。
我想查询姓名或身份证。我正在做这个
SELECT * FROM foo WHERE foo.searchtext @@ to_tsquery('1234 & abcd');
它工作正常,但现在我想删除拼写错误,例如,如果名称是 abcd,我输入 abbd,那么它应该得到所有可能的值。
我见过 pg_tgrm()
但它 does not 与整数或 tsvector
我尝试使用其他选项 pg_tgrm()
就像我将索引存储在另一个字段 searchtextstring 中,类型为 text 和查询
select *
from foo
where searchtextstring % '123' and searchtextstring % 'abbd';
但我不认为这是有效的,而且这对打字错误不起作用。
那么如何处理 to_tsquery 的拼写错误?
谢谢
全文搜索仅忽略词干和大小写的差异,不会让您根据相似性查找匹配项。
pg_trgm
是要走的路。
我用这个样本table:
CREATE TABLE foo (id integer PRIMARY KEY, searchtextstring text);
INSERT INTO foo VALUES (1, 'something 0987');
INSERT INTO foo VALUES (2, 'abbd 1224');
CREATE INDEX ON foo USING gist (searchtextstring gist_trgm_ops);
这太小了,PostgreSQL 将始终使用顺序扫描,所以如果可能的话,让我们强制 PostgreSQL 使用索引(以便我们可以模拟更大的 table):
SET enable_seqscan = off;
现在查询:
EXPLAIN (COSTS off)
SELECT * FROM foo WHERE searchtextstring % '1234'
AND searchtextstring % 'abcd';
QUERY PLAN
--------------------------------------------------------
Index Scan using foo_searchtextstring_idx on foo
Index Cond: ((searchtextstring % '1234'::text)
AND (searchtextstring % 'abcd'::text))
(2 rows)
索引使用的很好,单次索引扫描!
但是查询returns没有行:
SELECT * FROM foo WHERE searchtextstring % '1234'
AND searchtextstring % 'abcd';
id | searchtextstring
----+------------------
(0 rows)
不是因为“不行”,而是词不够相似。别忘了一个四字的字里没有那么多八卦,换一个字母就没那么相似了。这并不奇怪,对吧?
所以我们必须降低相似度阈值才能得到结果;
SET pg_trgm.similarity_threshold = 0.1;
SELECT * FROM foo WHERE searchtextstring % '1234'
AND searchtextstring % 'abcd';
id | searchtextstring
----+------------------
2 | abbd 1224
(1 row)