Regex с конструктором запросов Doctrine 2?

В соответствии с заголовком, как можно совместить регулярное выражение с конструктором запросов Doctrine 2? В основном я пытаюсь создать уникальные слизни.

Вот моя текущая реализация. Я генерирую слизню. Затем я проверяю, есть ли какие-либо пули, используемые в этом пуле. Если есть, я добавлю - {number} в конец пули, где {number} - самое меньшее число, которое еще не используется.

$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().'-%');

Проблема здесь LIKE slug% может соответствовать foo-bar-1, foo-bar-2, и foo-bar-not-the-same-slug. Что было бы чище - это регулярное выражение, которое ищет REGEX slug - (\ d +) или что-то подобное.

Как сделать это с помощью построителя запросов Doctrine 2?

Ответ 1

добавить DoctrineExtensionsBundle - обновите свой композитор .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-совместимые регулярные выражения

Ответ 2

REGEXP - это специфичная для вендора функция, поэтому сама Doctrine ее не поддерживает. Плюс это не функция, а оператор сравнения (см. Этот ответ). Но вы можете использовать функцию в поле для сравнения с другим значением. DoctrineExtensions (написанный автором доктрины) имеет код для включения регулярного выражения в 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 отлично подходит для моих нужд!

Ответ 3

Мне понравилось это

 $query->andWhere('REGEXP(r.status, :text) = 1')
       ->orWhere('REGEXP(r.comment, :text) = 1')
       ->setParameter('text',MY REGULAR EXP);

Ответ 4

Не тестировался (для MySQL):

$qb->where(new Doctrine\ORM\Query\Expr\Comparison(
    'o.slug', 'REGEXP', ':slug')
);
$qb->setParameter('slug', '^'.$slug->__toString().'-[[:digit:]]+$');