【问题标题】:Postgres full text search and spelling mistakes (aka fuzzy full text search)Postgres 全文搜索和拼写错误(又名模糊全文搜索)
【发布时间】:2020-05-07 16:18:38
【问题描述】:

我有一个场景,我需要能够搜索用于非正式通信的数据。因此我想要全文搜索,但我也想要理解拼写错误。问题是如何考虑拼写错误才能进行模糊全文搜索?

非常简短Postgres Full Text Search is Good Enough 中讨论过,文章讨论了拼写错误。

所以我已经建立了一个“文档”表,创建了索引等。

CREATE TABLE data (
  id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, 
  text TEXT NOT NULL);

我可以创建一个额外的 tsvector 类型的列并相应地索引...

alter table data 
  add column search_index tsvector 
  generated always as (to_tsvector('english', coalesce(text, ''))) 
  STORED;

create index search_index_idx on data using gin (search_index);

例如,我有一些文本,其中数据显示“气球”,但有人可能会搜索“气球”,所以我插入两行(故意拼写错误)...

insert into data (text) values ('baloon');
insert into data (text) values ('balloon');

select * from data;

id |  text   | search_index
----+---------+--------------
 1 | baloon  | 'baloon':1
 2 | balloon | 'balloon':1

...并对数据执行全文搜索...

select * from data where search_index @@ plainto_tsquery('balloon');

 id |  text   | search_index
----+---------+--------------
  2 | balloon | 'balloon':1
(1 row)

但是我没有得到拼写错误版本“baloon”的结果......所以使用链接文章中的建议,我已经建立了我词典中所有单词的查找表,如下所示......

"你可以通过在你的 tsquery 中附加相似的词位来获得好的结果"

CREATE TABLE data_words AS SELECT word FROM ts_stat('SELECT to_tsvector(''simple'', text) FROM data');

CREATE INDEX data_words_idx ON data_words USING GIN (word gin_trgm_ops);

...我可以搜索可能拼错的相似词

从 data_words 中选择 word,similarity(word, 'balloon') 作为相似度,其中similarity(word, 'balloon') > 0.4 order bysimilarity(word, 'balloon');

  word   | similarity
---------+------------
 baloon  |  0.6666667
 balloon |          1

...但我如何在查询中实际包含拼写错误的单词?

上面的文章不就是这个意思吗?

select plainto_tsquery('balloon' || ' ' || (select string_agg(word, ' ') from data_words where similarity(word, 'balloon') > 0.4));

         plainto_tsquery
----------------------------------
 'balloon' & 'baloon' & 'balloon'
(1 row)

...插入实际搜索,但我没有得到任何行!

select * from data where text @@ plainto_tsquery('balloon' || ' ' || (select string_agg(word, ' ') from data_words where similarity(word, 'balloon') > 0.4));

select * from data where search_index @@ phraseto_tsquery('baloon balloon'); -- no rows returned

我不确定我在哪里出错了 - 有什么可以说明的吗?我觉得我非常接近实现这一目标......?

【问题讨论】:

  • 使用to_tsquery 并在两个选项之间构造一个带有| 的字符串。

标签: postgresql full-text-search fuzzy-search


【解决方案1】:
SELECT to_tsquery('balloon |' ||
                  string_agg(word, ' | ')
       )
FROM data_words
WHERE similarity(word, 'balloon') > 0.4;

【讨论】:

  • 大声笑,谢谢....我可以这样做...从 search_index @@ (select to_tsquery(string_agg(word, ' |')) from data_words where word % 'baloon') order by ts_rank_cd(search_index, 'baloon');这真的是您应该进行模糊全文搜索的方式吗?我的意思是它有点工作,但同时我无法摆脱我错过了一些东西(或很多东西)的感觉......
  • 我想是的。 PostgreSQL 中没有对模糊全文搜索的规定。您可以调查一个包含所有可能拼写错误的同义词词典。
  • 最终,这种查询与我想得到的一样接近...感谢您的帮助! select text, ts_rank_cd(search_index, 'baloon') from data where search_index @@ (select to_tsquery(string_agg(word, '|')) from data_words where word % 'baloon') order by ts_rank_cd(search_index, 'baloon') desc;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-14
  • 1970-01-01
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多