Doctrine2: Полиморфные запросы: поиск по свойствам подклассов
У меня есть проект, где я занимаюсь заказами клиентов. Некоторые из этих заказов осуществляются через Amazon.com. Таким образом, у меня есть объект Order и объект AmazonOrder, который его расширяет. Одна вещь, добавленная AmazonOrder, - это AmazonOrderId.
У меня есть требование реализовать широкую функцию поиска. Пользователь может вводить некоторые вещи в текстовое поле и использоваться в кучке выражений в одном большом where-clause. Так, например, если пользователь искал "111", результаты включают в себя любые заказы с идентификатором, начиная с 111, причем любой заказ отправляется в почтовые индексы, начинающиеся с 111, причем любой заказ отправляется на "111 Main St" и т.д..
Этот материал реализован с запросом, созданным запросом-построением, с большим выражением orX()
.
Теперь я хотел бы сопоставлять все заказы, но если они являются AmazonOrder, также совпадают с AmazonOrderId.
И я застрял - я подозреваю, что это будет невозможно
Вот как я создаю запрос:
$qb->select('o,s')->from('PMS\Entity\Order', 'o');
$qb->leftJoin('o.shippingInfo','s');
$qb->andWhere('o.status = :status');
$qb->setParameter('status',$status);
$qb->andWhere(
$qb->expr()->orX(
$qb->expr()->like('o.id',':query')
$qb->expr()->like('s.address',':query')
$qb->expr()->like('s.city',':query')
)
);
$qb->setParameter('query',$userQuery .'%');
$orders = $qb->getQuery()->getResult();
И я не могу понять, как добавить условие, которое говорит грубо: "ИЛИ (Заказ - это AmazonOrder AND AmazonOrderId LIKE" $userQuery% ') "
У кого-нибудь есть понимание? Либо способ справиться с этим, либо, по крайней мере, подтвердить, что это невозможно сделать таким образом?
Ответы
Ответ 1
Здесь другое решение, которое работает для меня с Doctrine 2.4:
$qb->select('o')
->from('Order', 'o')
->leftJoin('AmazonOrder', 'ao', 'WITH', 'o.id = ao.id')
->andWhere('o.id like :query or ao.amazonOrderId like :query')
->setParameter('query', $someQuery);
Вы только что ушли - присоединитесь к сущности в конкретном подклассе. (Вы можете адаптировать мой простой запрос к вашему прецеденту.)
Я пробовал это ровно один раз, но, похоже, он работает.
Ответ 2
Хм, у меня были похожие проблемы в моем последнем проекте доктрины.
Одно время это было всего лишь одно поле, поэтому я переместил его в родительский класс - не самое приятное решение, но работал. В другом случае там, где слишком много свойств, чтобы они загромождали родительский класс. Я выполнил собственный SQL-запрос для поиска и получения идентификаторов записей, а затем использовал WHERE IN (...)
dql для извлечения сущностей.
Компромисс может быть доктриной ResultSetMapping
, которая может напрямую сопоставить собственный SQL-запрос с объектами, хотя каждый раз, когда я работал с ним, я нашел его довольно неуклюжим в использовании и накладными расходами для двух запросов (выборки ids и fetch entites), как указано выше, чтобы быть пренебрежимым.
Возможно, вы могли бы выполнить что-то с оператором INSTANCEOF
в своем предложении WHERE
, хотя я не думаю, что доктрина будет достаточно умна, чтобы распознать ее так, как вы хотите.