Php Levenshtein搜索

Php Levenshtein搜索,php,mysql,levenshtein-distance,Php,Mysql,Levenshtein Distance,我在一个网站上工作,该网站出售我们说的东西,并提供“供应商搜索”。在该搜索中,您输入您的城市、邮政编码、地区和距离(以公里或英里为单位),然后网站将为您提供供应商列表 为此,我与供应商建立了一个数据库。在保存这些供应商的表单中,您输入他们的完整地址,当您单击“保存”按钮时,会向谷歌地图发出请求,以获取他们的纬度和经度 当有人进行搜索时,我会查看一张表,其中存储了所有搜索词及其lat/lng。 这张桌子看起来像 +--------+-------+------+ | term | lat

我在一个网站上工作,该网站出售我们说的东西,并提供“供应商搜索”。在该搜索中,您输入您的城市、邮政编码、地区和距离(以公里或英里为单位),然后网站将为您提供供应商列表

为此,我与供应商建立了一个数据库。在保存这些供应商的表单中,您输入他们的完整地址,当您单击“保存”按钮时,会向谷歌地图发出请求,以获取他们的纬度和经度

当有人进行搜索时,我会查看一张表,其中存储了所有搜索词及其lat/lng。 这张桌子看起来像

+--------+-------+------+
| term   | lat   | lng  |
+--------+-------+------+
因此,第一个查询非常简单

select lat, lng from my_search_table where term = "the term"
如果我找到一个结果,我会用一个好方法搜索访问者想要的范围内的所有供应商,并将结果打印在地图上

如果找不到结果,我会使用levenshtein函数进行搜索,因为人们编写bruxelle或bruxeles而不是bruxelles是非常常见的事情,我不想一直向google maps发出请求(我的表中还有一个“搜索了多少次”列以获取一些统计数据)

因此,我请求不带where子句的搜索时间,并循环遍历所有结果以获得距离内的最小LevensInner。如果最小的结果大于2,我请求谷歌地图的坐标

这是我的问题。对于一些国家(我们在世界各地有多个网站),我的搜索表有15-20k+个条目。。。php不(真的)喜欢在这样的数据上循环(我完全理解),我的请求在php超时下。我可以增加这个超时时间,但几个月后问题就会一样

所以我尝试了一个levensteinmysql函数(顺便说一句),但速度也很慢


所以我的问题是“即使在非常大的数据集上,是否有任何方法可以使搜索速度更快?”

您可以尝试MySQL函数


您可以使用kd树或三元树来加快搜索速度。这个想法是使用二进制搜索

我的建议基于三点:

  • 首先,您的数据集很大。这意味着——它足够大,可以拒绝“全选”+“在PHP应用程序中运行”的想法
  • 其次,您可以控制您的数据库。因此,您可以调整一些与架构相关的内容
  • 最后,
    SELECT
    查询的性能是最重要的,而添加新数据的性能并不重要
事情是你不能执行快速的levenshtein搜索,因为levenshtein本身非常慢。我的意思是,计算levenshtein距离是件很慢的事情。因此,仅使用“智能搜索”无法解决此问题。你必须准备一些数据

可能的解决方案是:创建一些组索引,并在添加/更新数据时分配它。这意味着-您将存储额外的列,该列将存储一些散列(例如,数字)。添加新数据时,您将:

  • 使用levenshtein距离执行搜索(为此,您可以使用您的应用程序,也可以使用您(已经提到)的函数,针对插入的数据对表中的所有记录进行搜索)
  • 将新行的组索引设置为上一步中找到的行的索引值
  • 如果未找到任何内容,请设置一些新的组索引值(它位于第一行,并且还没有类似的行),这将不同于表中已经存在的任何组索引值

要搜索所需的行,您只需选择具有相同组索引值的行。这意味着:您的选择查询将非常快。但是-是的,这将在添加/更改数据时造成极大的开销。因此,它不适用于执行更新/插入操作时的情况。

尽管我无能为力,但+1表示格式良好d答案。Levenshtein距离比使用Soundex发现拼写错误要好得多,所以我怀疑这将是一个好的解决方案。嗨,David,谢谢你的回答。不幸的是,我不认为听起来像对我有帮助。根据MySQL文档,它与英语的配合非常好,但我们有很多“欧洲utf8语言”,西里尔语,阿拉伯语,甚至亚洲语言。+1;准备数据通常是一个值得权衡的问题,插入速度只慢一点,但选择速度要快得多
SELECT lat, lng FROM my_search_table WHERE term SOUNDS LIKE "the term"