Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP + MySql] Wyszukiwarka z BOOLEAN MODE
Forum PHP.pl > Forum > PHP
wiliams
Mam problem z dłuższymi (np dwuwyrazowymi) frazami w wyszukiwarce.

Poniższa funkcja to wyszukiwarka produktów. Jeśli wpiszemy dłuższą frazę. Np "Renault Clio", zwróci produkty, które w nazwie mają "Renalut" lub "Clio", tymczasem chciałby aby zwracała jako wynik, tylko te produkty,w których opisie jest zarówno "Reanlut" oraz "Clio". Wyczytałem w manualu, ze to kwestia +, ale niestety nie działa.

  1. function searchProd($Page = 1,$Strings = null,$UrlString = null,$Caturl = null,$CatID = null){
  2. global $DB;
  3. $PerPage = PROD_PER_PAGE;
  4. if($Page > 1)$Offset = ($Page - 1)*$PerPage; else $Offset = 0;
  5.  
  6. if ($Strings) {
  7. $Words = trim($Strings);
  8. $StrArr = explode(' ',$Strings);
  9. $wordCount = count($StrArr);
  10. foreach ($StrArr as $key=>$Word) {
  11. //$Word = preg_replace('/[^a-zA-Z0-9]/', '', $Word);
  12. if (strlen($Word)>0){
  13. if (strlen($Word)>1) $MatchExpr.= " +$Word* ";
  14. elseif (strlen($Word)>0) $MatchExpr.= " $Word* ";
  15. $MatchTitleExpr.= " $Word* ";
  16. }
  17. }
  18. }
  19.  
  20. if ($UrlString) {
  21. $StrArr = explode('-',$Strings);
  22. $wordCount = count($StrArr);
  23. foreach ($StrArr as $key=>$Word) {
  24. if (strlen($Word)>0){
  25. if (strlen($Word)>1) $MatchExpr.= " +$Word* ";
  26. elseif (strlen($Word)>0) $MatchExpr.= " $Word* ";
  27. if (strlen($Word)>0) $Words.= $Word.' ';
  28. }
  29. }
  30. }
  31.  
  32. if($CatID !== null)
  33. {
  34. $WhereCat = ' AND pc.categories_id = ' . $CatID;
  35. }
  36.  
  37.  
  38. $this->StrArr = $StrArr;
  39. $this->SelectSQL = "SELECT
  40. p.*, p.$this->PriceColumn as price,
  41. m.manufacturename,
  42. MATCH(pd.all) AGAINST('{$MatchExpr}' IN BOOLEAN MODE) AS allrelevance,
  43. MATCH(pd.name) AGAINST('{$MatchTitleExpr}' IN BOOLEAN MODE) AS namerelevance
  44. FROM
  45. products p
  46. RIGHT JOIN products_details pd ON (p.productid=pd.prodid)
  47. LEFT JOIN manufactures m ON (m.manufactureid=p.manufacturer)
  48. LEFT JOIN products_categories pc ON (pc.products_id = p.productid)
  49. WHERE (MATCH(pd.all) AGAINST ('$MatchExpr' IN BOOLEAN MODE)) $WhereCat
  50. GROUP BY productid ";
  51. if ($Page == 1) $this->RelevantCategsSQL = "SELECT
  52. DISTINCT `products_categories`.`categories_id`
  53. FROM
  54. `products_details`
  55. INNER JOIN `products_categories` ON `products_details`.`prodid` = `products_categories`.`products_id`
  56. WHERE MATCH(`products_details`.`all`) AGAINST('$MatchExpr' IN BOOLEAN MODE) $WhereCat
  57. ";
  58. $this->SelectSQL.= "ORDER BY namerelevance DESC,allrelevance DESC, p.name ASC LIMIT $Offset, $PerPage";
  59. if ($Caturl || $CatID) $this->CountSQL = "SELECT
  60. COUNT(*) AS `TotalProducts`
  61. FROM
  62. `products_details`
  63. LEFT JOIN products_categories pc ON (pc.products_id = `products_details`.prodid)
  64. WHERE (MATCH(`all`) AGAINST('$MatchExpr' IN BOOLEAN MODE)) $WhereCat
  65. GROUP BY prodid ";
  66. else $this->CountSQL = "SELECT
  67. COUNT(*) AS `TotalProducts`
  68. FROM
  69. `products_details`
  70. WHERE (MATCH(`all`) AGAINST('$MatchExpr' IN BOOLEAN MODE))
  71. GROUP BY prodid
  72. ";
  73.  
  74. $DB->Query($this->SelectSQL,'searchProd');
  75. while ($row = $DB->Fetch('searchProd')) {
  76. $row['producturl'] = strtr($row['producturl'], array('%' => '-'));
  77. $this->Products[$row['productid']] = $row;
  78. $this->Products[$row['productid']]['count'] = ++$Offset;
  79. }
  80. //Update the value
  81. if ($Page == 1 && strlen($Words) >= 4 && count($this->Products) >= 1 && $this->blockSearchWords($Words)) {
  82. $Words = trim(strtr($Words, array(
  83. '+' => ' '
  84. )));
  85. if ($CatID) $sql = "INSERT INTO `searches` (`phrase`,`times`,`cat`) VALUES ('$Words','1','$CatID') ON DUPLICATE KEY UPDATE `times`=`times`+1";
  86. else $sql = "INSERT INTO `searches` (`phrase`,`times`) VALUES ('$Words','1') ON DUPLICATE KEY UPDATE `times`=`times`+1";
  87. $DB->Query($sql,'InsertSearcherString');
  88. }
  89. return $this->Products;
  90.  
  91. }
erugio
Wydaje mi się, że problem polega na generowaniu zmiennej $MatchExpr. Wg. manuala (http://dev.mysql.com/doc/refman//5.5/en/fulltext-boolean.html) obrabiany String musisz sprowadzić od postaci:
'+Reanlut +Clio'

  1. if ($Strings) {
  2. $Words = trim($Strings);
  3. // Tutaj powinieneś stawić zmienną $Words (po trim'ie)
  4. $StrArr = explode(' ',$Words);
  5. $wordCount = count($StrArr);
  6. $MatchExpr = "";
  7. foreach ($StrArr as $key=>$Word) {
  8. if (strlen($Word)>0){
  9. $MatchExpr .= " +$Word ";
  10. // w przykładach (w manualu) nie było użytego +Word* - może nie można używać dwóch znaków
  11. // Może spróbuj dodać jeszcze osobno słowo:
  12. // $MatchExpr .= " $Word* ";
  13. $MatchTitleExpr.= " $Word* ";
  14. }
  15. }
  16. }
  17.  
  18.  

[/quote]
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.