PostgreSQL使用Levenshtein模糊搜索多个单词

时间:2015-07-03 04:09:40

标签: postgresql levenshtein-distance fuzzy-search

我正在研究一个postgreSQL查询,以便在我正在处理的应用中搜索公司的名称时允许模糊搜索功能。我发现并一直在与Postgres' Levenshtein方法(fuzzystrmatch模块的一部分),并且大多数情况下它正在工作。但是,只有当公司的名称是一个单词时才会起作用,例如:

使用Apple(它作为简单的苹果存储在数据库中)我可以运行以下查询并使其完美地工作(它返回levenshtein距离为0):

SELECT * FROM contents 
  WHERE levenshtein(company_name, 'apple') < 4;

然而,当我采用与索尼相同的方法(存储在索尼电子公司的数据库中)时,我无法获得任何有用的结果(进入索尼时,levenshtein距离为16)。

我试图通过将公司的名称分解为单个单词并单独输入每个单词来解决此问题,从而产生如下结果:

user input => 'sony'

SELECT * FROM contents 
  WHERE levenshtein('Sony', 'sony') < 4 
  OR levenshtein('Electronics', 'sony') < 4 
  OR levenshtein('INC', 'sony') < 4;

所以我的问题是:有什么方法可以用我现在的常规方法准确地实现多字模糊搜索,或者我是在寻找完全错误的地方?

谢谢!

1 个答案:

答案 0 :(得分:2)

根据Levenshtein插入(10000),删除(100)和替换(1)的野外值给出您的数据和以下查询:

id()

输出是这样的:

with sample_data as (select 101 "id", 'Sony Entertainment Inc' as "name"
                      union
                     select 102 "id",'Apple Corp' as "name")
select sample_data.id,sample_data.name, components.part,
       levenshtein(components.part,'sony',10000,100,1) ld_sony
from sample_data
inner join (select sd.id,
                   lower(unnest(regexp_split_to_array(sd.name,E'\\s+'))) part
            from sample_data sd) components on components.id = sample_data.id
  • 第1行 - 没有变化..
  • 第2行 - 第9行删除和3次更改
  • 第3行 - 1次插入和2次更改
  • 第4行 - 1次删除和4次更改
  • 第5 - 3行更改

我发现,当你给出一个门槛时,将这些词分开会导致很多误报。您可以通过Levenshtein距离订购靠近顶部的更好的匹配位置。也许调整Levenshtein变量可以帮助您更好地订购匹配。可悲的是,Levenshtein并没有像以后的变化那样对早期的变化做出不同的重视。