有没有办法根据字符串相似性过滤django查询集(la python difflib)?

cet*_*eek 8 django similarity django-queryset

我需要将冷线索与我们客户的数据库相匹配.

这些销售线索来自第三方提供商(数千条记录),销售人员要求我们(用他们的话说)"过滤掉我们的客户",这样他们就不会试图将我们的服务卖给老牌客户.

显然,线索中存在拼写错误.Charles成为Charlie,Joseph成为Joe等等.所以我不能真正做一个过滤器,比较lead_first_name和client_first_name等.

我需要使用某种字符串相似性机制.

现在我正在使用可爱的difflib将引导的名字和姓氏与生成的列表进行比较Client.objects.all().它可以工作,但由于客户端的数量,它往往很慢.

我知道大多数sql数据库都有soundex和差异函数.在下面的更新中查看我对它的测试 - 它不像difflib那样有用.

还有其他解决方案吗?有更好的解决方案吗?

编辑:

至少在我的数据库中,Soundex的表现不如difflib.

这是一个简单的测试 - 在包含"Joseph Lopes"的表格中查找"Joe Lopes":

with temp (first_name, last_name) as (
select 'Joseph', 'Lopes'
union
select 'Joe', 'Satriani'
union
select 'CZ', 'Lopes'
union
select 'Blah', 'Lopes'
union
select 'Antonio', 'Lopes'
union
select 'Carlos', 'Lopes'
)
select first_name, last_name
  from temp
 where difference(first_name+' '+last_name, 'Joe Lopes') >= 3
 order by difference(first_name+' '+last_name, 'Joe Lopes')
Run Code Online (Sandbox Code Playgroud)

以上返回"Joe Satriani"作为唯一的比赛.即使将相似度阈值降低到2也不会将"Joseph Lopes"作为潜在匹配.

但是difflib做得更好:

difflib.get_close_matches('Joe Lopes', ['Joseph Lopes', 'Joe Satriani', 'CZ Lopes', 'Blah Lopes', 'Antonio Lopes', 'Carlos Lopes'])
['Joseph Lopes', 'CZ Lopes', 'Carlos Lopes']
Run Code Online (Sandbox Code Playgroud)

在gruszczy的回复后编辑:

在编写自己的文档之前,我查找并在所有知识库中找到了Levenshtein Distance的T-SQL实现.

在测试中,它仍然不会比difflib做更好的匹配工作.

这让我研究了difflib背后的算法.这似乎是一个修改版本中的拉特克利夫-Obershelp算法.

不幸的是,我似乎无法找到一些已经根据difflib创建了一个T-SQL实现的灵魂......我会尽力尝试.

如果没有其他人在接下来的几天内得到更好的答案,我会将其授予gruszczy.谢谢,亲切的先生.

gru*_*czy 2

soundex不会帮助你,因为它是一个语音算法。Joe 和 Joseph 在语音上并不相似,因此 soundex 不会将它们标记为相似。

您可以尝试Levenshtein distance,它是在 PostgreSQL 中实现的。也许也在您的数据库中,如果没有,您应该能够编写一个存储过程,它将计算两个字符串之间的距离并在计算中使用它。