如何搜索具有误差范围的特定string
?
示例:
我有一个带有以下value
的table
:
品牌表
- 品牌:松下,型号:15T
- 品牌:苹果,型号:IPHONE 7
- 品牌:三星,型号:Galaxy S8
- 品牌:微软,M15
我想找到一个有3个错误字符的巧合。对于这个例子,我的输入是M$crosoft,我希望它返回Microsoftrow
。或者,如果我输入Pnasonic,它应该输入Panasonicrow
。
如何在不牺牲性能的情况下实现这一目标?简单的方法是比较每个字符和3个错误的计数器,但我需要性能,因为品牌table
大约有200K+row
s。
p.S我是用PHP编码的。
您可能希望使用Metaphone和Levenstein的组合。(针对拼写错误)
http://php.net/manual/en/function.metaphone.php
和
http://php.net/manual/en/function.levenshtein.php
Metaphone处理声音,所以一个"糟糕"的例子是,你可以把它看作是去掉元音,把一些复合音改成单个字母(几乎像速记)。因此,使用您的示例
$sound1 = metaphone('M$crosoft');
echo "$sound1n";
$sound2 = metaphone('Microsoft');
echo "$sound2n";
输出
MKRSFT
MKRSFT
正如你所看到的,它们是匹配的。
你可以在这里测试
http://sandbox.onlinephpfunctions.com/code/716471f5fed18268a2dc0aea800b3db634d9616f
性能由于运行隐喻会带来额外的开销,我建议预先计算您搜索的单词的声音索引,并将其保存在数据库中。然后,当你运行用户搜索时,你对他们的搜索词运行相同的metaphone
函数,并使用它来搜索表中的声音索引。通过这种方式,你可以预先加载构建声音索引的成本,并且只需要做一次(或当记录被编辑时)
然而,您可能会发现匹配过于宽松,在这种情况下,您可以使用Levenstein。这将根据需要的更改来计算两个单词之间的差异。例如插入、更新和删除需要进行的操作,甚至可以对操作进行加权。
$len = levenshtein ('M$crosoft', 'Microsoft');
echo "$lenn";
//as you can see the arguments are $str1, $str2, insert cost, replace cost, delete cost
//so we can control what weight we get for each operation.
$len = levenshtein ('M$crosoft', 'Microsoft', 1,2,1);
echo "$lenn";
Ouputs
1
2
现在,如果你需要将其与可能变得非常复杂的"Bunch"文本相结合,因为你必须在DB上使用全文搜索。
这不是小事。
也许更好的选择是考虑使用Sphinx这样的全文搜索引擎。把它设置成基本的样子并不难。但它也不是一颗神奇的子弹,所以你必须做一些事情,比如词干、词形等
同样不是微不足道的,但它确实比MysqlDB、有更好的全文搜索
http://sphinxsearch.com/
性能我可以告诉你,在文本搜索方面,它很快,可能比MySql快20倍,但它也有自己的怪癖。但我强烈推荐它。我们每分钟在我们的小狮身人面像集群中进行大约15万次搜索,创下了1/4百万行的记录。(我们的主服务器是一个12核54GB的怪物)
这种类型的搜索没有一个确定的解决方案,或者至少我还没有找到(我已经做了很多)。