2011-02-10 90 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]."')  + 
    ... 

雖然這可能是一個好主意,用一個模式更適合於這種搜索