如何结合 PostgreSQL 文本搜索和 fuzzystrmatch

How to combine PostgreSQL text search with fuzzystrmatch

我希望能够从类型为 ts_vector 的列中查询单词,但是编辑距离小于 X 的所有内容都应被视为匹配项。

像这样 my_table 是:

id | my_ts_vector_colum             | sentence_as_text
------------------------------------------------------
1  | 'bananna':3 'tasty':2 'very':1 | Very tasty bananna
2  | 'banaana':2 'yellow':1         | Yellow banaana
3  | 'banana':2 'usual':1           | Usual banana
4  | 'baaaanaaaanaaa':2 'black':1   | Black baaaanaaaanaaa

我想查询类似“给我所有行的 ID,其中包含单词 banana 或与 banana 相似的单词,其中相似意味着它的 Levenshtein 距离小于 4”。所以结果应该是1、2和3。

我知道我可以做类似 select id from my_table where my_ts_vector_column @@ to_tsquery('banana'); 的事情,但这只会让我得到完全匹配。

我也知道我可以做类似 select id from my_table where levenshtein(sentence_as_text, 'banana') < 4; 的事情,但这只适用于文本列,并且只有在匹配项只包含单词 banana 时才有效。

但我不知道是否或如何将两者结合起来。

P.S。 Table 我要执行此操作的位置包含大约 200 万条记录,查询应该非常快(肯定少于 100 毫秒)。

P.P.S - 我可以完全控制 table 的架构,因此更改数据类型、创建新列等都是完全可行的。

200 万个短句子包含的不同单词可能比这少得多。但如果你所有的句子都有“创意”拼写,也许不是。

因此,您也许可以创建一个 table 个不同的词,以便使用未索引的距离函数相对快速地进行搜索:

create materialized view words as 
    select distinct unnest(string_to_array(lower(sentence_as_text),' ')) word from my_table;

并为更大的table创建一个精确的索引:

create index on my_table using gin (string_to_array(lower(sentence_as_text),' '));

然后一起加入:

select * from my_table join words 
   ON (ARRAY[word] <@ string_to_array(lower(sentence_as_text),' ')) 
   WHERE levenshtein(word,'banana')<4;