2011-08-09 3 views
1

제품 카탈로그에 대한 검색 기능을 만들고 있습니다. 여기

<form name="search" method="post" action="'.$PHP_SELF.'"> 
    <div> 
    Search for: <input type="text" name="find" /> 
    <input type="hidden" name="searching" value="yes" /> 
    <input type="submit" name="search" value="Search" /> 
    </div> 
</form> 

이 일치하는 MySQL 데이터베이스를 쿼리 쿼리입니다 :이 모두가 완벽하게 잘 작동

SELECT * FROM `products` WHERE upper(`desc`) LIKE'%$find%' 

에 대한 사용자 검색 여기

지금까지 입력 코드 한 단어 문자열.

여기서 문제는 사용자가 두 단어 문자열을 검색 할 때 이러한 문자열이 별도의 기능과 관련이있는 것처럼 일치하지 않는 것입니다.

당신의 등 초콜릿 바, 초콜릿 상자, 초콜릿의 패킷 ...

지금은 비록 몇 가지를 얻을 :

이의 예는 것은, 제품 카탈로그는 다양한 초콜릿에 대한 정보가 포함되어 있습니다 desc 필드에 들어있는 설명에는 초콜릿 및 바라는 단어가 포함되어 있으며 일부는 "회사 바 120g 초콜릿"과 같은 변형을 포함합니다.

desc 입력란에 설명이 명시 적으로 포함되어 있지 않으면 사용자가 "초콜릿 바"를 검색하면 일치가 반환되지 않으므로 위 코드에서 문제가 발생합니다.

내가 원하는 것은 사용자가 "초콜릿 바"를 검색하여 "초콜릿"및 "바"라는 바리 티가 포함 된 모든 일치 항목이 반환되는 것입니다.

누구나 내가이 작업에 대해 어떻게 생각하는지 입력 할 수 있습니까?

$find을 배열로 만들고 구분 기호를 구분 기호로 사용 하시겠습니까?

+1

이것은 어떤 카테고리/태그를위한 것입니까? –

+0

@Tomalak 안녕하세요! 나는 이것에 아주 새로운데, 나는이 카테고리들과 태그들을 살펴볼 것이다. –

+0

인간이 읽을 수있는 "설명"을 통해 검색하도록 강요하는 대신, 색인을 생성하고 색인을 생성하며 검색 할 수 있습니다. –

답변

1

은 아마 당신은 같은 것을 할 수 products로부터

SELECT *를 WHERE desc LIKE '%이 %'

출력 $find = 'this and that'을위한 :

SELECT * products FROM WHERE desc LIKE '%이 %'OR desc LIKE '% 및 %'OR desc LIKE '% 그 %'

이 확실히 매우 기본적인 기능이지만, 당신이 얻을 생각.

1

문자열을 부분으로 분할하고 모두 where 절에 별도로 추가해야합니다. 예 :

.... WHERE `desc` LIKE '%bar%' OR `desc` LIKE '%chocolate%' 

그러나 다소 느린 쿼리 일 수 있습니다. SQL의 와일드 카드 검색은 어쨌든 느리고 여러 개의 와일드 카드로 문제가 복잡해집니다.

FULLTEXT을 사용하면 더 빠른 결과를 얻을 수 있습니다. 추가 데이터베이스 설정 작업이 필요하지만 더 중요한 것은 FULLTEXT은 일반적으로 색인에서 짧은 단어를 삭제하기 때문에 사용자가 제공 한 예에서는 유용하지 않을 것입니다. 구성이 가능하기 때문에 작동시킬 수 있지만 FULLTEXT은 큰 텍스트 블록에 대한 검색 색인을 작성하는 것입니다. 짧은 문자열을위한 것은 아닙니다.

이런 종류의 문제에 대한 일반적인 해결책은 태그 지정을 사용하고 문자열 대신 태그를 검색하는 것입니다. 기본적으로 각 레코드의 모든 관련 키워드가 개별 테이블에 저장되어 개별적으로 저장됩니다. 이렇게하면 와일드 카드를 완전히 없앨 수 있기 때문에 매우 빠르게 검색 할 수 있습니다. 실제 텍스트에없는 동의어 키워드를 추가하여 검색을 훨씬 쉽게 사용할 수 있습니다.

사용자가 태그 작성 솔루션으로 원하는 것을 실제로 찾을 수없는 경우에도 여전히 "고급"검색을 제공 할 수 있으며, 이는 와일드 카드 솔루션으로 돌아갑니다.그들이 천천히 움직일 것이라는 것을 그들이 확실히 알고 있는지 확인하십시오.

+0

그리고 이것은 전체 단어 검색을하지 않습니다. 입력 토큰에서 영리한 FULLTEXT 검색을 구성하는 것을 선호합니다. –

+0

desc는 예약어입니다. 다시 진드기로 기입하십시오. – Jacob

+0

그것은 내가 줄을 따라 생각하고 있었던 것이다. 그러나 실제로 당신은 요점을 제시합니다. 다소 빠른 접근 방법에 대한 제안이 있습니까? 물론 @cularis - –

1

당신은 거 무겁고 무거운 얻을 수 있습니다 전체 텍스트 인덱스 Documentation

desc LIKE '%word%' 으로 보일 것입니다. 사용자는 2 단어 이상을 제공 할 수도 있습니다. 그냥 더 많은 단어로 쿼리를 중단하고 모든 posibilities을 포함 where 절 구축 :

WHERE desc LIKE '%word1%' or desc LIKE '%word2%' OR .... 

가 다시이, FULLTEXT 매우 효율적이거나 빠르지 + MATCH 반대가 더 잘 작동합니다.

$keywords_array = explode(' ', $find); 

$qry = "SELECT * FROM `products` WHERE `desc` LIKE '%" 
     . implode("%' OR `desc` LIKE '%", $keywords_array) 
     . "%'"; 

출력 $find = 'this'에 대한 :

0

regexp로 표류하는 것은 어떻습니까?

당신은 "OK"시뮬레이션 $find에서 | (또는 무엇이든 입력 구문 당신이 선호)와 공백을 대체 할 수

"초콜릿"=> "초콜릿 | 바" (또는 "\ B를 (초콜릿 | 막대기) \ B를 " 당신이 단어 경계를 필요로하는 경우)

하거나 시뮬레이션 다음으로 변환 할 수 있습니다" "

"초콜릿 "=>"초콜릿과 * 바 ".

다음 실행 :

WHERE desc REGEXP '$find'

번 확인 성능이 당신을 위해 확인됩니다.

0

첫 번째 문제는 검색을 단일 단어로 분리하는 것입니다. 이것은 PHP 자체로 쉽게 할 수 있지만 검색 결과에 따라 구문을 사용할 수도 있습니다. "this is a phrase" 그렇지 않은 경우 검색 텍스트를 공백으로 쉽게 분할 할 수 있습니다.

두 번째 문제에 대해서는 가능한 해결책이 이미 게시되었습니다. ... LIKE 'chocolate% OR LIKE 'bar%을 사용할 수 있습니다 (참고 : 단어 뒤에 % 만 추가 했으므로 wordparts를 다음과 같이 찾으려면 제외). 뿐만 아니라hocol은 여전히 ​​초콜렛과 일치해야합니다. 색인을 사용할 수 없기 때문에 이것은 매우 느립니다!

더 좋은 해결책은 fulltext search이고 MATCH()... AGAINST()을 사용하는 것이 좋습니다.이 솔루션은 전체 텍스트 색인을 사용하고 검색 속도를 크게 높입니다.