使用Levenshtein距离的PHP / MySQL搜索引擎

时间:2015-06-28 22:06:02

标签: php mysql search pdo levenshtein-distance

我正在尝试创建一个简单的搜索引擎,用户可以在其中查询数据库并返回匹配的结果接近其查询。起初我只是使用通配符(%)来查找与用户搜索相关的结果。 PHP的内容看起来像这样:

// Users search terms is saved in $_POST['q']
$q = $_POST['q'];
// Prepare statement
$search = $db->prepare("SELECT `id`, `name` FROM `users` WHERE `name` LIKE ?");
// Execute with wildcards
$search->execute(array("%$q%"));
// Echo results
foreach($search as $s) {
  echo $s['name'];
}

上述代码运行正常,但是相当有限。虽然它可以获取接近但不完全匹配用户查询的结果(因为通配符),但它仍然不会返回所有相关结果;用户的查询仍然必须与数据库中的某些内容完全匹配。例如,如果我有一个名为" Tim"作为一排,寻找" Timothy"不会工作。所以我的新方法看起来像这样:

// Users search terms is saved in $_POST['q']
$q = $_POST['q'];
// Create array for the names that are close to or match the search term
$results = array();
foreach($db->query('SELECT `id`, `name` FROM `users`') as $name) {
  // Keep only relevant results
  if (levenshtein($q, $name['name']) < 4) {
    array_push($results,$name['name']);
  }
}
// Echo out results
foreach ($results as $result) {
  echo $result."\n";
}

此代码在技术上有效,然而,效率非常低,我想知道如何改进它。最大的问题是,由于必须从数据库中检索所有结果然后排序,因此会创建一个不必要的大型SQL查询,这尤其成问题,因为我有数据库。此外,我想知道简单地使用levenshtein函数是否足以获得相关结果,或者是否有更好的方法来整理不相关的结果。我提出了一些其他方法来对相关结果进行排序:

if (levenshtein(metaphone($q), metaphone($name['name'])) < 4) {
  array_push($results,$name['name']);
}

if (similar_text(metaphone($q), metaphone($name)['name']) < 2) {
  array_push($results,$name['name']);
}

if (similar_text($q, $name['name']) > 2) {
 array_push($results,$name['name']);
}

我认为将levenshteinmetaphone一起使用可能实际上效果最好,因为它会更好地考虑简单的拼写错误。但是我不确定哪种方法最好用,特别是考虑到我现在这样做的方式已经非常昂贵了(大型SQL查询+在循环中发生的昂贵功能)&# 39; t表现良好)。

提前致谢

0 个答案:

没有答案