模糊自动完成

时间:2015-06-02 08:36:12

标签: mysql autocomplete soundex metaphone

在我的应用程序中,我有一个用户表,first_namelast_name。我目前有第三列full_name(自动生成),如下所示:first_name + last_name + first_name(没有特殊字符)。

"Etienne", "De Crécy", "Etienne De Crecy Etienne"

现在,我有一个简单的算法来自动完成用户输入(删除了特殊字符):

SELECT * FROM users WHERE full_name LIKE "%input%"

此查询返回Etienne,其中包含输入Crécy EtienneEtienne DeCréCreEtienne

我想在此查询中添加一些模糊以允许用户误导。当用户写道时,这个新算法应该能够返回Etienne:

  • Etiene(与名字相似)
  • Etienne Crecy(类似于全名,没有特征)
  • Crecy Etienne(类似于全名,没有特别的,其他方向)
  • De Cressi(听起来像姓氏)
  • Cressi(听起来像姓氏,没有特别之处)

我做了很多搜索,最相关的想法是使用SOUNDEX方法(或Metaphone程序)或levenstein程序。我无法使用作为,因为:

  • Soundex基于第一个字母,然后SOUNDEX(Cressy)SOUNDEX(De cressy)不同,即使它们非常相似。
  • Metaphone取决于字母的位置(以'kn'开头就像是'n'乞讨,但仅限于第一位)
  • levenstein不关心字符串长度:De Cressy与Cressy不相似。

您对“混合”这些方法有什么想法,或者您对我有任何其他想法吗?

1 个答案:

答案 0 :(得分:0)

我强烈建议您尝试使用Solr或Elasticsearch来满足您的要求(以及更高的灵活性和更好的性能)。

但是,如果你想在MySQL中复制一个基本的语音搜索引擎,你需要能够在插入时按full_name提取多个令牌(单词或单词编码)(以及自动完成时的每个查询)。

1)。首先,确保您的full_name列的类型为FULLTEXT。然后切换到MATCH...AGAINST查询语法代替LIKE %foo%

这将为您购买精确的内部令牌匹配,如“de cressy”的“cressy”。

您使用Levenshtein距离作为排序标准的想法并不错,但运行成本很高,因此请确保LIMIT MATCH...AGAINST ORDER BY MATCH... DESC查询和{{1}如果您要输出 levenshtein(query,full_name)作为select的一部分。

  

目标是避免在所有行上运行 levenshtein

2)。如果您仍然有兴趣扩展结果以包含声音相似

创建一个 phonetic_token 表,其中一个外键列返回到您的主名称表(它是一对多关系名称到令牌)。

将列soundexmetaphone添加到此表中。

将记录插入主名称表时,另外在空白处解析它们,并插入soundex&将每个名字的metaphone编码转换为phonetic_token

您可能需要添加一些解析逻辑,以确保记录所有名字三倍和姓氏三倍(例如,在语音编码之前,请确保“de cressy”标记为“de”,“cressy”和“decressy”为了匹配预期的输入。)

现在,在查询要显示的声音完成名称时,您实际上将使用phonetic_token WHERE soundex IN加入您的主要名称表(查询令牌的soundex代码列表 )或metaphone IN(来自查询令牌的 metaphone代码列表)。

我建议在MATCH(full_name)...AGAINST(query_text)产生的结果太少的情况下,将此语音匹配作为第二个查询运行。

同样,Solr或Elasticsearch将通过配置为您完成所有这些文本争论,同时为您提供更快捷的性能。根据应用程序的范围,从MySQL中提取文本匹配可能会为您节省大量时间和麻烦。