2011-02-10 97 views
0

可能重复:
PHP MySQL Search And Order By Relevancy如何用字优先relevence订购MySQL的搜索结果

嗨,

我有包含像姓名字段数列的表,地址,公司等可以说有人搜索“微软约翰”。我希望包含“微软”的结果应该先出现,然后包含约翰的结果。反之,如果查询是“约翰·微软”

我的PHP代码:

$searchitems=explode(" ", $trimmed); 
//print_r($searchitems); 
$so = $_GET['so']=='2'?"2":"1"; 

$clause = $so=='2'?"AND":"OR"; 
include("dbconnect.php"); 
// Build SQL Query 

$query = "select FirstName,LastName,course,Department,batch,City,companyjob,companylocation, 
    companyposition,coursename,institutename,coursename2,institutename2,coursename3, 
    institutename3 from alumni WHERE "; 
for($i=0;$i<count($searchitems);$i++) 
{ 
    $queryappend .= "(FirstName LIKE '".$searchitems[$i]."%' OR LastName LIKE '".$searchitems[$i]."%' 
    OR City LIKE '".$searchitems[$i]."%' OR CountryorRegion LIKE '".$searchitems[$i]."%' 
    OR companyjob LIKE '".$searchitems[$i]."%' OR companylocation LIKE '".$searchitems[$i]."%' 
    OR coursename LIKE '".$searchitems[$i]."%' OR institutename LIKE '".$searchitems[$i]."%' 
    OR coursename2 LIKE '".$searchitems[$i]."%' OR institutename2 LIKE '".$searchitems[$i]."%')"; 
    if($i<count($searchitems)-1) $queryappend .= $clause; 

} 
$query .=$queryappend; 

是MySQL是通过排序ID的结果的问题。这使得它很有趣,因为一些高价值的结果可能是陷入堆栈深处。顺便说一句,phpmyadmin搜索具有相同的缺陷。

请建议。

+2

的不知道它在PHP或在phpMyAdmin一个缺陷。我在您的声明中根本没有看到__any__ ORDER BY子句,因此返回的订单将始终是纯粹的任意(甚至不能通过ID保证) – 2011-02-10 10:46:12

+0

感谢Mark回复。我需要对搜索查询中的单词序列进行排序。正如我在我的示例中所说的,如果第一个$ searchitems是microsoft,则应首先显示包含microsoft的所有结果。 (微软的结果可能会被下一个$ searchitems等进一步排序)。我不能添加任何任意的顺序,因为这会破坏目的。 – hiprakhar 2011-02-10 10:53:36

回答

2

举个例子:

SELECT 
    FirstName, 
    LastName, 
    IF (FirstName LIKE '%Microsoft%' || LastName LIKE '%Microsoft%', 1, 0) AS One, 
    IF (FirstName LIKE '%John%' || LastName LIKE '%John%', 1, 0) AS Two 
FROM alumni 
ORDER BY One DESC, Two DESC 

在你的代码,这将使查询相当复杂。优点是,具有两个搜索项的项目出现在仅匹配单个搜索项的项目之前。

另一种方法是在使用PHP检索记录的同时将记录排序为桶。假设你已经在一个数组$search的搜索字词(由优先级从高到低排列):

while ($record = mysql_fetch_array($result)) 
{ 
    $total = join(' ', $record); 
    $found = false; 
    foreach ($search as $term) 
    { 
    if (strpos($total, $term) !== false) 
    { 
     $buckets[$term][] = $record; 
     $found = true; 
     break; 
    } 
    } 
    if (!$found) 
    { 
    $results[] = $record; 
    } 
} 
foreach (array_reverse($search) as $term) 
{ 
    if (isset($buckets[$term])) 
    { 
    $result = array_merge($buckets[$term], $result); 
    } 
} 

现在,你必须在阵列$results结果。请注意,这演示了该算法,它未针对性能进行调整。

0

我想最简单的方法来解决它将排序的结果levenstein distance

喜欢的东西....

$queryappend="ORDER BY 
    length(firstname) - levenshtein(FirstName, '".$searchitems[$i]."') + 
    length(lastname) - levenstein(LastName, '".$searchitems[$i]."') + 
    length(City)  - levenstein(City, '".$searchitems[$i]."')  + 
    ... 

虽然这可能是一个好主意,用一个模式更适合于这种搜索