Как получить случайную строку с помощью Doctrine2 querybuilder? - PullRequest
7 голосов
/ 05 июня 2011

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

$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 не имеет случайной функции?

Ответы [ 2 ]

11 голосов
/ 05 июня 2011

Метод 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);

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

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

3 голосов
/ 06 сентября 2015

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

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

...