1

Тема: Поиск по фильтрам DQL

Добрый день.
Задача: отфильтровать всех пациентов по введённым в форму фильтрам.
В таблице patients есть одна запись с параметрами:
patient: {
   "name":"some name",
   "surname":"some surname",
}
Посылаем запрос на маршрут GET api/patients?name=some name&surname=some surname

Далее в методе (action) контроллера производим выборку

$dql="SELECT p FROM ".Patient::class." p  
                WHERE p.name LIKE :name
                  AND p.surname LIKE :surname"

$q = $this->_em->createQuery($dql);
$q->setParameter('name', array_get($params, 'name', '%%'));
$q->setParameter('surname', array_get($params, 'surname', '%%'));
 
return $q->getResult()

И всё работает. Но если например в форму не введён surname, то у нас получается такая конструкция "WHERE p.name LIKE 'some name' AND p.surname LIKE '%%'"
То есть AND p.surname LIKE '%%' вызывается напрасно. и мы напрасно отбираем производительность у запроса.
Так же если бы нам нужен был не LIKE а Equels(=), то у нас вообще данная выборка бы ничего не возвращала так как при отсутствии surname мы бы получали строку запроса в виде: "WHERE p.name = 'some name' AND p.surname =''".
Кончено  можно сделать свои инструменты для авто генерации DQL WHERE строки, но Это довольно распространённая задача. Неужели нет инструмента? Как люди делают подобные вещи в Doctrine 2?

2

Re: Поиск по фильтрам DQL

Dtri пишет:

Как люди делают подобные вещи в Doctrine 2?

Через QueryBuilder.

Если у вас запрос с переменным числом/составом условий, то вполне очевидно, что написать под него полноценный DQL одной строкой вы не сможете. Собирайте его конструктором. Есть surname? Добавили что-то вроде

$q->andWhere($q->expr()->like('LOWER(p.surname)', ':surname'))
    ->setParameter('surname', '%' . mb_strtolower($surname) . '%');

Нет? Не добавили.
И никаких проблем.