postgresql - 如何将 PostgreSQL 文本搜索与模糊字符串匹配相结合
问题描述
我希望能够从 type 的列中查询单词,ts_vector
但是所有具有低于 X 的 levenshtein 距离的东西都应该被认为是匹配的。
像这样的东西在哪里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,其中包含单词香蕉或类似于香蕉的单词,其中相似意味着它的 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;
,但这仅适用于文本列,并且仅当匹配项仅包含单词香蕉时才有效。
但我不知道是否或如何将两者结合起来。
我要执行此操作的 PS 表包含大约 200 万条记录,并且查询应该非常快(肯定少于 100 毫秒)。
PPS - 我可以完全控制表的架构,因此更改数据类型、创建新列等是完全可行的。
解决方案
大概 200 万个短句包含的不同单词要少得多。但如果你所有的句子都有“创造性”的拼写,也许不是。
因此,您也许可以创建一个不同单词的表,以便使用未索引的距离函数相对快速地搜索:
create materialized view words as
select distinct unnest(string_to_array(lower(sentence_as_text),' ')) word from my_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;
推荐阅读
- scala - Scala 类中已初始化变量,但打印的内容为空?
- angular - 使用 Angular 2 生成 Docx 文件
- r - 在回归模型上使用预测
- python - 如何从熊猫的列中删除列表中存在的字符串
- firebase - 具有自定义登录到 firebase 的 Flutter 应用程序获取:FIRAuthErrorDomain,自定义令牌对应于不同的受众
- c# - 使用计数的用户尝试
- c# - 控制器操作未收到请求正文中的内容
- c# - HashAlgorithm.Create 在 C# ASP.NET Core 2 中因 PlatformNotSupportedException 而失败
- python - 迭代 SQLAlchemy ResultProxy 的每一列
- swing - 将 Applet 应用程序迁移到 Java 11