Как получить случайную строку с помощью построителя запросов Doctrine2?

Пока у меня есть:

$qb1 = $this->getEntityManager()->createQueryBuilder();
            $qb1->select('s')
                ->from('\My\Entity\Song', 's')
                ->where('s.id <> ?1')
                ->orderBy('RAND()', '')
                ->setMaxResults(1)
                ->setParameters(array(1=>$current->id));

Но доктрина2 этого не понимает:

Error: Expected end of string, got '('

Даже на их странице построителя запросов ничего нет. Вы хотите сказать мне, что лучшая ORM для php не имеет случайной функции?


person Tjorriemorrie    schedule 05.06.2011    source источник
comment
Здесь и здесь — два примера в Doctrine 1.2. Я предполагаю, что что-то подобное сработает для Doctrine 2.   -  person David Weinraub    schedule 05.06.2011


Ответы (2)


Метод orderBy должен принимать поле Song для целей сортировки (например, «s.author» или «s.title»), а не случайное значение. Даже если вы выбрали случайное поле для упорядочивания, например случайный выбор одного поля в php, это вовсе не будет очень случайным, потому что вы всегда получите первый результат для текущих критериев сортировки. Если ваши песни имеют 8 полей, вы получите только 8 разных песен в результатах поиска, даже если у вас их тысячи.

Вот предложение:

$qb1->select('s')
    ->from('\My\Entity\Song', 's')
    ->where('s.id <> ?1')
    ->setMaxResults(1)
    ->setParameters(array(1=>$current->id))
    ->setFirstResult($offset);

Здесь $offset может быть случайным значением, которое вы получаете в php с помощью функций rand() или mt_rand(). Конечно, $offset должен быть меньше, чем общее количество песен. Это всего лишь предложение, есть много способов сделать это.

ИМХО, я считаю, что Doctrine2 — это необыкновенная ORM, и нет ничего более продвинутого, чем она. Я предполагаю, что вы прочитали раздел Конструктор запросов справочного руководства. , но я также предлагаю вам прочитать DQL, в котором объясняется, какие функции доступны в системе запросов Doctrine и как вы можете создать свои собственные (!).

person faken    schedule 05.06.2011
comment
Настолько необычно, что вы не можете просто ORDER BY RAND(). - person darkbluesun; 24.02.2016

Вам нужно добавить пользовательскую функцию DQL RAND. Для фреймворка symfony2 вы можете просто добавить в конфигурацию:

doctrine:
    orm:
        entity_managers:
            default:
                dql:
                    numeric_functions:
                        rand: DoctrineExtensions\Query\Mysql\Rand

И добавьте вам зависимости в composer.json:

composer require beberlei/DoctrineExtensions

Тогда решение для получения 100 случайных AcmeBundle:Item объектов будет таким же простым, как:

$em = $this->getContainer()->get('doctrine')->getManager();
$messages = $em->createQueryBuilder()
    ->select('i, RAND() AS HIDDEN r')
    ->from('AcmeBundle:Item', 'i')
    ->orderBy('r', 'ASC')
    ->setMaxResults(100)
    ->getQuery()
    ->getResult();

Примечание. Предполагается, что вы используете серверную часть MySQL или MariaDB. Для SQLite или PostGreSQL вам может понадобиться другой класс реализации.

person ioleo    schedule 06.09.2015