2011-02-10 3 views
0

가능한 중복 :
PHP MySQL Search And Order By Relevancy어떻게 단어 우선 순위의 relevence에 의해 MySQL의 검색 결과를 정렬하는

안녕하세요, 이름과 같은 필드를 포함하는 여러 열이있는 테이블이

, 주소, 회사 등. 누군가 "microsoft john"을 검색한다고합시다. 나는 "microsoft"를 포함하는 결과가 먼저 나타나야하고, 그 다음에 john을 포함하는 결과가 나타나기를 바랍니다. 그 반대의 경우도 마찬가지 쿼리

내 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로 결과를 주문한다하는 문제 ... 일부 높은 평가 결과가 될 수 있기 때문에, 그것은 재미 있습니다 스택에 깊이 붙어 있습니다. btw, phpmyadmin 검색에는 동일한 결함이 있습니다.

좋습니다. 예를 들어

+2

를 검색하는 이런 종류 스키마 더 적합 사용할 수 있습니다 있지만

뭔가 같은 ....

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

는 확실하지가 하나 PHP 또는 phpMyAdmin을의 결함이다. 귀하의 진술에 __any__ ORDER BY 절이 전혀 표시되지 않으므로 반환 된 순서는 항상 순전히 임의적입니다 (심지어 ID로 보장되지 않습니다) –

+0

답장을 보내 주셔서 감사합니다. 검색 쿼리에서 단어 순서를 ORDER BY해야합니다. 나의 예에서 말했듯이 첫 번째 $ searchitems가 마이크로 소프트이면 마이크로 소프트를 포함하는 모든 결과가 먼저 표시되어야한다. (마이크로 소프트 결과는 다음 $ searchitems 등으로 더 주문할 수 있습니다). 그 목적을 망칠 수있는대로 임의의 순서를 추가 할 수는 없습니다. – hiprakhar

+0

추천 한 페이지 http://stackoverflow.com/questions/344199/php-mysql-search-and-order-by-relevancy는 검색어 문자열에서 개별 단어를 검색하도록 요청하는 것입니다. 나는 explode() 함수를 사용하여 그 효과를 얻었습니다. – hiprakhar

답변

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

Thanks @oswald !! 그게 효과가 있었어!코드를 작성하는 데 소중한 시간을 할애 해 주셔서 감사합니다.하지만 아마도 @sfussenegger에주의를 기울여 전체 텍스트 검색으로 이동하게 될 것입니다. 전체 텍스트 검색이 첫 번째 및 두 번째 (버킷) 방법보다 효율적입니까? 아마 – hiprakhar

+0

. 그렇지 않으면 전체 텍스트 검색이 mysql에 포함되지 않을 것이다. – Oswald

+0

마침내 검색 시스템이 변경되었습니다. (이름, 성, 이름, 웹 페이지) 수정 ('$ 트림 된'검색어 확장 포함) 다음은 일치하지 않습니다. (일치하는 성명, 이름, 성, 부서, 도시, CountryorRegion, companyjob, companylocation, coursename, institutename, coursename2, institutename2, altemail, addcomments, 나는 아직도 더 많은 robost를 만들기 위해 fulltext의 점수 부분으로 더 많은 것을 실험하고있다. 이 일을 도와 주신 모든 분들께 감사드립니다! @symcbean에게 levenshtein의 좋은 아이디어를주는 특별한 감사 ... 그것은 좋은 읽을 거리였습니다 ...이 운동은 저의 학사 학위를 마치고 인터뷰 할 때 도움이 될 것입니다! – hiprakhar

0

나는 이것을 해결하는 가장 간단한 방법은 levenstein distance에 의해 결과를 정렬하는 것이라고 생각합니다. 좋은 생각이