2017-02-07 17 views
0

У меня есть два столбца в таблице first_name и last_name (PostgreSQL).Должен ли я реализовать полнотекстовый поиск в этом случае? альтернативы?

У меня есть вход, позволяющий пользователям искать людей. Это поле автозаполнения, которое вызывает веб-службу для поиска людей по именам и/или фамилиям.

В настоящее время, я сделал запрос (с помощью моего построитель запросов):

 $searches = preg_split('/\s+/', $search); 

     if (!empty($search)) { 
      $orX = $query->expr()->orX(); 
      $i = 0; 
      foreach ($searches as $value) { 
       $orX->add($query->expr()->eq('c.firstName', ':name'.$i)); 
       $orX->add($query->expr()->eq('c.lastName', ':name'.$i)); 
       $query->setParameter('name'.$i, $value); 
       $i++; 
      } 
      $query->andWhere($orX); 
     } 

Но этот запрос не так точно, как это требуется, он использует OR для каждого слова, так что если я ищу " Расмус Лердорф ", он также дает мне" Расмус Адамс "и" Адель Лердорф ". Он работает только в том случае, если я ввожу одно слово (например, «Расмус»), в этом случае он дает мне всех людей с «Расмусом» как first_name или last_name.

Я прочитал о MATCH AGAINST, но я использую PostgreSQL. Я также слышал о функции полнотекстового поиска в PostgreSQL в качестве эквивалента MATCH AGAINST, но мне интересно, будет ли реализация полнотекстового поиска излишней для такой цели (тем более, что максимальное количество слов в обоих столбцах не будет превышать 4).

Прошу вас, пожалуйста, ваши советы, ваша обычная помощь всегда ценится. Спасибо

ответ

0

Вам не нужен полнотекстовый поиск.

Просто добавьте различные условия поиска с AND вместо OR:

$i = 0; 
foreach ($searches as $value) { 
    $orX = $query->expr()->orX(); 
    $orX->add($query->expr()->eq('c.firstName', ':name'.$i)); 
    $orX->add($query->expr()->eq('c.lastName', ':name'.$i)); 
    $query->setParameter('name'.$i, $value); 
    $i++; 
    $query->andWhere($orX); 
} 

Я также хотел бы предложить использовать LIKE вместо сравнения на равенство (добавить «%» в начале и в конце поиска пользователей термин) , и, вероятно, также сделать все без учета регистра, добавив $query->expr()->lower() соответственно.