2016-10-26 5 views
0

Может кто-нибудь помочь мне с обычным поиском? Я просто не могу понять это. Мой поиск работает, только если я набираю 1 слово. Но если я напечатаю 2,3,4, ... слова это не сработает.Symfony/Doctrine - Поиск

Пример: POLYKARBONÁTOVÉ POUZDRO Н.А. MACBOOK (Поликарбонат чехол для Macbook)

Если я типа искать вход только "pouzdro" он возвращает все крышки. Если я напечатаю «Polykarbonátové pouzdro», он ничего не вернет. Если я набираю «Polykarbonátové», он ничего не возвращает.

Вот мой код:

if ($keyword != null) { 
     $keyword = strtolower(preg_replace('/\p{Mn}/u', '', \Normalizer::normalize($keyword, \Normalizer::FORM_KD))); 
     $keywords = explode(' ', $keyword); 
     $i = 0; 
     foreach ($keywords as $key) { 
      $i++; 
      if ($i == 1) { 
       $qb->where("p.title LIKE :keyword$i"); 
      } else { 
       $qb->andWhere("p.title LIKE :keyword$i"); 
      } 
      $qb->setParameter("keyword$i", "%" . $key . "%"); 
     } 
    } 

Спасибо :)

EDIT: запросов из журнала (я использую PostgreSQL):

[2016-10-26 16:47:11] doctrine.DEBUG: SELECT p0_.id AS id_0, p0_.serial_number AS serial_number_1, p0_.title AS title_2, p0_.url AS url_3, p0_.note AS note_4, p0_.views AS views_5, p0_.price AS price_6, p0_.bought_price AS bought_price_7, p0_.old_price AS old_price_8, p0_.is_active AS is_active_9, p0_.is_accessory AS is_accessory_10, p0_.is_special AS is_special_11, p0_.quantity AS quantity_12, p0_.created_at AS created_at_13, p0_.updated_at AS updated_at_14, p0_.details_id AS details_id_15, p0_.accessory_category_id AS accessory_category_id_16 FROM products p0_ WHERE p0_.title LIKE ? ["%polykarbonatove%"] []

[2016-10-26 16:53:52] doctrine.DEBUG: SELECT p0_.id AS id_0, p0_.serial_number AS serial_number_1, p0_.title AS title_2, p0_.url AS url_3, p0_.note AS note_4, p0_.views AS views_5, p0_.price AS price_6, p0_.bought_price AS bought_price_7, p0_.old_price AS old_price_8, p0_.is_active AS is_active_9, p0_.is_accessory AS is_accessory_10, p0_.is_special AS is_special_11, p0_.quantity AS quantity_12, p0_.created_at AS created_at_13, p0_.updated_at AS updated_at_14, p0_.details_id AS details_id_15, p0_.accessory_category_id AS accessory_category_id_16 FROM products p0_ WHERE p0_.title LIKE ? AND p0_.title LIKE ? ["%polykarbonatove%","%pouzdro%"] []

ответ

0

Так,

  1. Вы действительно не нужен этот

    LOWER() // LIKE is not case sensitive 
    
  2. Попробуйте очистить свой код, вы должны кода на этом пути

    foreach ($keywords as $key) { 
        $i++; 
        if ($i == 1) { 
         $qb->where("p.title LIKE :keyword$i"); 
        } else { 
         $qb->andWhere("p.title LIKE :keyword$i"); 
        } 
        $qb->setParameter("keyword$i", "%" . $key . "%"); 
    } 
    
  3. Вы можете открыть файл журнала и дать нам реальный запрос, доктрина try (var/cache/logs/dev.log)

+0

Я отредактировал мой вопрос :) –

0

Проблема, с которой вы столкнулись, связана не с количеством искомых терминов, а с акцентами.

Если вы хотите выполнить поиск без акцентов, вы можете изменить сортировку на utf8_general_ci, что не требует акцента.

Чтобы изменить параметры сортировки с доктриной, вы должны реализовать пользовательскую функцию DQL, как описано here и реализован в this answer от hattila:

namespace MyCompany\MyBundle\DQL; 

use Doctrine\ORM\Query\AST\Functions\FunctionNode; 
use Doctrine\ORM\Query\Lexer; 

class CollateFunction extends FunctionNode 
{ 
    public $expressionToCollate = null; 
    public $collation = null; 

    public function parse(\Doctrine\ORM\Query\Parser $parser) 
    { 
     $parser->match(Lexer::T_IDENTIFIER); 
     $parser->match(Lexer::T_OPEN_PARENTHESIS); 
     $this->expressionToCollate = $parser->StringPrimary(); 

     $parser->match(Lexer::T_COMMA); 

     $parser->match(Lexer::T_IDENTIFIER); 
     $lexer = $parser->getLexer(); 
     $this->collation = $lexer->token['value']; 

     $parser->match(Lexer::T_CLOSE_PARENTHESIS); 
    } 

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) 
    { 
     return sprintf('%s COLLATE %s', $this->expressionToCollate->dispatch($sqlWalker), $this->collation); 
    } 
} 

Затем добавьте его в Symfony as explained here.

+0

Спасибо, так должно быть? или $ qb-> где ("p.title LIKE COLLATE (: ключевое слово $ i, utf8_general_ci)"); ? Причина: Я получил это: SQLSTATE [42704]: неопределенный объект: 7 ОШИБКА: сопоставление «utf8_general_ci» для кодирования «UTF8» не существует –

+0

После изучения вашей ошибки кажется, что вам придется изменить сортировку всей базы данных для сопоставления 'C', поскольку postgresql не позволяет изменять сортировку таким образом. Я предлагаю вам посмотреть этот ответ http://stackoverflow.com/a/35795540/4074148 или другие, но я думаю, что это выходит за рамки этого вопроса. – Veve

Смежные вопросы