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

使用Levenshtein距离的PHP/MySQL搜索引擎,php,mysql,search,pdo,levenshtein-distance,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

我正在尝试创建一个简单的搜索引擎,用户可以在其中查询数据库,并返回匹配和接近其查询的结果。起初,我只是使用通配符(
%
)来查找与用户搜索相关的结果。用于该项目的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'];
}
// 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";
}
上面的代码工作正常,但是相当有限。虽然它可以获取接近但与用户查询不完全匹配的结果(因为有通配符),但它仍然不会返回所有相关结果;用户的查询仍然必须与数据库中的某些内容完全匹配。例如,如果我有一个以“Tim”为行的数据库,搜索“Timothy”将不起作用。因此,我的新方法如下所示:

// 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'];
}
// 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";
}

我认为将
levenshtein
metaphone
结合使用可能实际上效果最好,因为它最好考虑到简单的拼写错误。但我不确定哪种方法是最好的,尤其是考虑到我现在使用的方法已经非常昂贵(大型SQL查询+循环中发生的昂贵函数对性能来说不是好兆头)


提前感谢

以前有人去过那里。他们总是会发现数据库(或者数据库和服务器端代码的组合)对搜索引擎不好,然后他们发现lucene,它对你所想的东西(levenshtein,拼音距离)有很好的实现,还有很多其他你没有的东西。此外,随着数据量的增加,您可以使用基于lucene的solr或elasticsearch扩展到多个节点。您可以尝试PostgreSQL,它可以对单词进行标记——它的全文搜索功能比MySQL更全面。要将Tim/Timothy放在同一个根目录下,可以使用同义词库功能。
$name
是一行,包含数据库中的
id
name
列。。。。您不是针对
name
值进行测试,而是针对row@MarkBaker哇,真是个愚蠢的错误,我不知道我怎么没看到。我更新了问题,删除了错误(因为它更多的只是一个语法错误,将来对其他人没有帮助),并对其进行了编辑,以更准确地反映我试图学习的内容。
if (similar_text($q, $name['name']) > 2) {
 array_push($results,$name['name']);
}