Многословный поиск в PHP/MySQL

Я изо всех сил пытаюсь создать поиск, который ищет несколько слов. Моя первая попытка не дала никаких результатов и заключается в следующем:

  require_once('database_conn.php');
  if($_POST){
  $explodedSearch = explode (" ", $_POST['quickSearch']);


  foreach($explodedSearch as $search){
  $query = "SELECT * 
            FROM jobseeker 
            WHERE forename like '%$search%' or surname like '%$search%' 
            ORDER BY userID 
            LIMIT 5";
  $result = mysql_query($query);
}

while($userData=mysql_fetch_array($result)){
    $forename=$userData['forename'];
    $surname=$userData['surname'];
    $profPic=$userData['profilePicture'];
    $location=$userData['location'];

    echo "<div class=\"result\">
    <img class=\"quickImage\" src=\"" . $profPic. "\" width=\"45\" height=\"45\"/>
    <p class=\"quickName\">" . $forename . " " . $surname . "</p>
    <p class=\"quickLocation\"> " . $location . "</p>
    </div>";

}
}  

Я также попробовал следующее, что дало результаты, но, как вы можете себе представить, я получал повторяющиеся результаты для каждого введенного слова:

if($_POST){
$explodedSearch = explode (" ", $_POST['quickSearch']);


foreach($explodedSearch as $search){
$query = "SELECT * 
          FROM jobseeker 
          WHERE forename like '%$search%' or surname like '%$search%' 
          ORDER BY userID 
          LIMIT 5";
$result .= mysql_query($query);


while($userData=mysql_fetch_array($result)){
    $forename=$userData['forename'];
    $surname=$userData['surname'];
    $profPic=$userData['profilePicture'];
    $location=$userData['location'];

    echo "<div class=\"result\">
    <img class=\"quickImage\" src=\"" . $profPic. "\" width=\"45\" height=\"45\"/>
    <p class=\"quickName\">" . $forename . " " . $surname . "</p>
    <p class=\"quickLocation\"> " . $location . "</p>
    </div>";
}
}
}

Я в значительной степени в недоумении, как поступить с этим, любая помощь будет принята с благодарностью.

РЕДАКТИРОВАТЬ:

if($_POST){
$quickSearch = $_POST['quickSearch'];
$explodedSearch = explode (" ", trim($quickSearch));


$queryArray = array();

foreach($explodedSearch as $search){
$term = mysql_real_escape_string($search);
$queryArray[] = "forename like '%" . $term .  "%' surname like '%" . $term . "%'";
}

$implodedSearch = implode(' or ', $queryArray);

$query="SELECT *
        FROM jobseeker
        WHERE ($implodedSearch)
        ORDER BY userID
        LIMIT 5";

$result = mysql_query($query);

while($userData=mysql_fetch_array($result, MYSQL_ASSOC)){
    $forename=$userData['forename'];
    $surname=$userData['surname'];
    $profPic=$userData['profilePicture'];
    $location=$userData['location'];


    echo "<div class=\"result\">
    <img class=\"quickImage\" src=\"" . $profPic. "\" width=\"45\" height=\"45\"/>
    <p class=\"quickName\">" . $forename . " " . $surname . "</p>
    <p class=\"quickLocation\"> " . $location . "</p>
    </div>";

}
}

person Richie    schedule 13.12.2011    source источник


Ответы (4)


Я некоторое время работал над той же темой (поиск по ключевым словам), и вот как я это сделал:

$words = $_POST['keywords'];
if(empty($words)){
    //redirect somewhere else!
}
$parts = explode(" ",trim($words));
$clauses=array();
foreach ($parts as $part){
    //function_description in my case ,  replace it with whatever u want in ur table
    $clauses[]="function_description LIKE '%" . mysql_real_escape_string($part) . "%'";
}
$clause=implode(' OR ' ,$clauses);
//select your condition and add "AND ($clauses)" .
$sql="SELECT * 
      FROM functions 
      WHERE
      user_name='{$user_name}'
      AND ($clause) ";
$results=mysql_query($sql,$connection);
 if(!$results){
    redirect("errors/error_db.html");
 }
 else if($results){
 $rows = array();
<?php 
 while($rows = mysql_fetch_array($results, MYSQL_ASSOC))
{
   // echo whatever u want !
}
?>

-- Вот как это выглядело, когда я пытался запустить его с ПОЛНОТЕКСТОВЫМ поиском: Но вы должны установить тип таблицы как "MyISAM"

<?php
$words = mysql_real_escape_string($_POST['function_keywords']);
if(empty($words)){
    redirect("welcome.php?error=search_empty");
}
//if the columns(results)>1/2(columns) => it will return nothing!(use "NATURAL LANGUAGE"="BOOLEAN")
$sql="SELECT * FROM functions
     WHERE MATCH (function_description)
     AGAINST ('{$words}' IN NATURAL LANGUAGE MODE)";
$results=mysql_query($sql,$connection);
 if(!$results){
    redirect("errors/error_db.html");
 }
 else if($results){
$rows = array();
while($rows = mysql_fetch_array($results, MYSQL_ASSOC))
{
     // echo 
}
}
?>
person Med Akram Z    schedule 13.12.2011
comment
Использование LIKE '%x%' не использует индексы, просто чтобы вы знали. - person Dejan Marjanović; 13.12.2011
comment
в чем разница между использованием индекса или нет? - person Med Akram Z; 13.12.2011
comment
Ваш поиск будет довольно медленным на больших таблицах. Прочитайте это en.wikipedia.org/wiki/Index_%28database%29 - person Dejan Marjanović; 13.12.2011
comment
Итак, я должен заменить этот метод полнотекстовым поиском? - person Med Akram Z; 13.12.2011
comment
Эй, спасибо за внимание, ваш ответ кажется наиболее похожим на уровень, над которым я сейчас работаю. Единственное, я получаю следующую ошибку: Предупреждение: mysql_fetch_array(): предоставленный аргумент не является допустимым ресурсом результатов MySQL, и я понятия не имею, почему - person Richie; 13.12.2011
comment
я думаю, это потому, что запрос сначала не работал.. проверьте, действительно ли вы подключены к вашей базе данных и всем вашим переменным, и попробуйте еще раз.. - person Med Akram Z; 13.12.2011
comment
да, я тоже новичок, и я просто хочу поделиться информацией и помочь, но, как сказал другой парень, нам нужно что-то более мощное, так как это будет работать медленно на больших столах, но у меня это работает до сих пор. - person Med Akram Z; 13.12.2011
comment
Я отредактировал свой пост и добавил самую последнюю версию своего кода, я определенно подключен к базе данных, сайт не будет работать без подключения, и я включаю один и тот же файл подключения на каждую страницу. Я также не вижу никаких несоответствий в переменных. Думаю, это заставит меня рвать на себе волосы, ха-ха. - person Richie; 13.12.2011
comment
это трудно понять, но когда я нахожусь в чем-то подобном, я пытаюсь выполнить поиск по каждой строке, пока не доберусь до ошибки .. попробуйте вывести $sql на вашу страницу (просто /* все остальное и echo $sql; ) просто чтобы увидеть это, а затем примените оператор $sql в вашей команде phpmyadmin sql, чтобы увидеть, почему он не работает, и тогда проблема появится! (просто введите любые ключевые слова и эхо $sql и попробуйте). - person Med Akram Z; 13.12.2011
comment
Фантастический совет, мне не хватало слова ИЛИ в объединенной строке в цикле foreach. Мне потребовалось некоторое время, чтобы найти его даже с помощью phpMyAdmin. Но это был отличный совет, сэр, и я унесу его с собой в могилу. Мне нужно будет немного почитать об этих полнотекстовых поисковых запросах, когда я выпущусь, но я учусь на последнем курсе, и об этих вещах еще даже не было упоминания, поэтому я не знаю, насколько они будут актуальны для моего курса. Еще раз спасибо, вы фантастически помогли. - person Richie; 13.12.2011
comment
@Richie: Приятно, что это работает для вас, но эти OR и LIKE снизят производительность вашей базы данных. Возможно, вы захотите следить за своим журналом медленных запросов и запускать EXPLAINS. - person Mike Purcell; 13.12.2011
comment
@DigitalPrecision да, я понимаю, что вы имеете в виду, но количество OR вряд ли превысит 2 или 3, а база данных довольно мала. Это для университетского проекта, и они ни разу не упомянули нам о поиске FULLTEXT, модуль на самом деле даже не собирается маркировать нас по качеству нашего SQL, пока он работает. Но я обсужу со своим наставником, получу ли я больше оценок за FULLTEXT, и реализую, если да. Если нет, я обязательно почитаю об этом до того, как закончу учебу, чтобы у меня были хотя бы практические знания об этом. Спасибо за предупреждение о том, почему LIKE '%x%' является плохой практикой. - person Richie; 13.12.2011


Взгляните на MySQL полнотекстовый поиск, если необходимо использовать MySQL. В противном случае взгляните на SOLR, который представляет собой систему полнотекстового поиска. Вы можете использовать MySQL и SOLR в сочетании, чтобы обеспечить возможности поиска корпоративного уровня для ваших приложений.

person Mike Purcell    schedule 13.12.2011
comment
SOLR очень интересен, но выходит далеко за рамки того, над чем я сейчас работаю, а именно функций поиска и обмена сообщениями в социальной сети, которая создается как групповой проект для университета. Однако я добавлю ссылку, которую вы предоставили, в закладки и прочитаю ее для будущих проектов. Большое спасибо. - person Richie; 13.12.2011
comment
@RichieVikinglordTerry: Нет проблем. Вы определенно хотите проверить полнотекстовый поиск MySQL. Просто обратите внимание, что если вы реализуете fulltext, это можно сделать только для таблиц MyISAM (по сравнению с InnoDB). - person Mike Purcell; 13.12.2011

вот что я сделал

if (isset($_POST['search'])){
$words = mysql_real_escape_string($_POST['searchfield']);   
$arraySearch = explode(" ", trim($words));       
$countSearch = count($arraySearch);
$a = 0;
$query = "SELECT * FROM parts WHERE ";
$quote = "'";
while ($a < $countSearch)
{
  $query = $query."description LIKE $quote%$arraySearch[$a]%$quote ";
  $a++;
  if ($a < $countSearch)
  {
    $query = $query." AND ";
    }   
  }
    $result=mysql_query($query) or die(error);

//вы могли бы просто оставить это здесь, короткое и приятное, но я добавил дополнительный код, если он не выдает никаких результатов, тогда он ищет одно слово, а не оба слова//

$num = mysql_num_rows($result);
if ($num == 0){
 $a = 0;
 $query = "SELECT * FROM parts WHERE ";
while ($a < $countSearch)
{
  $query = $query."description LIKE $quote%$arraySearch[$a]%$quote ";
  $a++;
  if ($a < $countSearch)
  {
    $query = $query." OR ";
    $msg = "No exact match for: $words. Maybe this is what you're looking for though? If not please try again.";
    }

  }
  }
  $result=mysql_query($query) or die($query);
  if (mysql_num_rows($result) == 0){
    $msg = "No results, please try another search";
    }

}
person dragonvsphoenix    schedule 07.03.2013