Witam.

Posiadam problem z wyszukiwaniem in boolean mode.
Owo wyszukiwanie jest przeznaczone dla formularza jako sugestie.

Wygląda ono tak z przykładowymi danymi: Anna jantar zatańczyć z tobą

  1. SELECT id,name,url_name,MATCH(name) AGAINST('+"anna" +"jantar" +"przetańczyć" +"z" +"tobą"' IN BOOLEAN MODE) AS score FROM music WHERE MATCH(name) AGAINST('+"anna" +"jantar" +"przetańczyć" +"z" +"tobą"' IN BOOLEAN MODE) ORDER BY `score` ASC LIMIT 15



Nie daje wyników a informacje o piosence zawarte są w bazie po wpisaniu samego anna jantar pokazuje się ta piosenka na pierwszym miejscu.

Próbowałem na różne sposoby m. in. standardowo AGAINST('szukana fraza' IN BOOLEAN MODE), AGAINST('+szukana +fraza' IN BOOLEAN MODE), AGAINST('"szukana" "fraza"' IN BOOLEAN MODE) itd ale nie zawsze wyszukiwanie przynosi odpowiednie rezultaty na oko jego poprawność wynosi ok 30%.

W bazie jest ponad 500 tyś rekordów więc do PHP nie wrzucę tym bardziej do JS`a żeby wyszukiwanie przez nie.
Jeśli ma ktoś jakiś pomysł albo podpowiedź to z chęcią wysłucham.

----------------------

Problem rozwiązałem najprostszym sposobem może się komuś przyda zamieszczę.


  1. $text = urldecode($who);
  2. $text = preg_replace('/(-|\(|\)|&|\.|\+|")/',' ',$text);
  3. $text = preg_replace('/( +)/',' ',$text);
  4. $text = $db->escape($text);
  5. $text = preg_replace('/(\')/','',$text);
  6. $array = explode(' ',$text);
  7.  
  8. $count = count($array)-1;
  9. $sql = "";
  10. if($count == 0) {
  11. $sql = "(`name` LIKE '%".$array[0]."%')";
  12. }
  13. else {
  14. $i = 0;
  15. while ($i <= $count) {
  16.  
  17. $sql .= "(`name` LIKE '%".$array[$i]."%')";
  18.  
  19.   if($i != $count) : $sql .= " AND "; endif;
  20.  
  21. ++$i;
  22. }
  23.  }
  24. if ($result = $db->query("SELECT id,name,url_name FROM `music` WHERE ".$sql." LIMIT 15")) {
  25. return $result;
  26. }
  27. else {
  28. return false;
  29. }
  30. }


1. Skrypt usuwa zbędne znaki i przygotowuje frazę ($text) do zapytania
2. Rozbicie tekstu na tablicę
3. Jeśli text jest jednym słowem zostaje ustawione jedno zapytanie w przeciwnym razie wrzuca się w pętle która dopisuje dalsze części zapytania i jeśli $i != $count wstawia AND.

Zapytanie myślę że nie jest optymalne lecz jak najbardziej sprawne.

Wynik z profilera.
Cytat
Queries
SELECT id,name,url_name FROM `music` WHERE (`name` LIKE '%husaria%') AND (`name` LIKE '%bóg%') AND (`name` LIKE '%honor%') AND (`name` LIKE '%ojczyzna%') LIMIT 15
Time
0.000