我正在尝试创建一个简单的搜索引擎,用户可以在其中查询数据库并返回匹配和的结果接近其查询。起初我只是使用通配符(%
)来查找与用户搜索相关的结果。 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']);
}
我认为将levenshtein
与metaphone
一起使用可能实际上效果最好,因为它会更好地考虑简单的拼写错误。但是我不确定哪种方法最好用,特别是考虑到我现在这样做的方式已经非常昂贵了(大型SQL查询+在循环中发生的昂贵功能)&# 39; t表现良好)。
提前致谢