Regex с Doctrine 2 построителем запросов?
Согласно заголовку, как можно сопоставить регулярное выражение со сборщиком запросов Doctrine 2? В основном я пытаюсь генерировать уникальных слизней.
Вот моя текущая реализация. Я генерирую слизняк. Затем я проверяю, есть ли какие-нибудь слизни в использовании, как этот слизень. Если они есть, я добавлю -{число} в конец слага, где {число} - это наименьшее число, которое еще не используется.
$qb->select(array('partial o.{id, slug}'))
->from('Foo\Bar\Entity\Object', 'o')
->where($qb->expr()->like('o.slug', ':slug'));
$slug = new SlugNormalizer($text);
$qb->setParameter('slug', $slug->__toString().'-%');
Проблема здесь в том, что как slug% может соответствовать foo-bar-1, foo-bar-2 и AND foo-bar-not-the-the-slug. Что может быть чище, так это регулярное выражение, ищущее слизня REGEX -(\d+) или что-то подобное.
Есть ли способ сделать это с помощью построителя запросов Doctrine 2?
4 ответа
Добавьте DoctrineExtensionsBundle - обновите ваш composer.json:
"beberlei/DoctrineExtensions": "0.3.x-dev",
добавьте конфигурацию REGEXP - обновите ваше приложение /config.yml
doctrine:
orm:
dql:
string_functions:
regexp: DoctrineExtensions\Query\Mysql\Regexp
где когда-либо ваш QueryBuilder делает это:
$qb = $this->createQueryBuilder('x');
return $qb->andWhere('REGEXP(x.your_property, :regexp) = true')
->setParameter('regexp', '[[:digit:]]{3}') // insert your own regex here
->getQuery()->getResult();
и не забудьте использовать SQL-совместимые регулярные выражения
REGEXP является специфической функцией поставщика, поэтому сама Doctrine не поддерживает ее. Плюс это не столько функция сравнения, сколько оператор сравнения ( см. Этот ответ). Но вы можете использовать функцию на поле для сравнения с другим значением. DoctrineExtensions (написанный участником doctrine) содержит код для включения регулярного выражения в MySQL.
Пример из файла:
$query = $this->getEntityManager()->createQuery('SELECT A FROM Entity A WHERE REGEXP(A.stringField, :regexp) = 1');
$query->setParameter('regexp', '^[ABC]');
$results = $query->getArrayResult();
Если вы не хотите использовать DoctrineExtensions, вы можете написать свой собственный, следуя этому сообщению в блоге, или вы можете посмотреть на код для этого расширения Doctrine и написать свою собственную функцию DQL.
Я подтвердил, что REGEXP с использованием DoctrineExtensions отлично подходит для моих нужд!
Я так сделал
$query->andWhere('REGEXP(r.status, :text) = 1')
->orWhere('REGEXP(r.comment, :text) = 1')
->setParameter('text',MY REGULAR EXP);
Не проверено (для MySQL):
$qb->where(new Doctrine\ORM\Query\Expr\Comparison(
'o.slug', 'REGEXP', ':slug')
);
$qb->setParameter('slug', '^'.$slug->__toString().'-[[:digit:]]+$');