#symfony #doctrine-orm
#symfony #doctrine-orm
Вопрос:
Пока у меня есть:
$qb1 = $this->getEntityManager()->createQueryBuilder();
$qb1->select('s')
->from('MyEntitySong', 's')
->where('s.id <> ?1')
->orderBy('RAND()', '')
->setMaxResults(1)
->setParameters(array(1=>$current->id));
Но doctrine2 этого не понимает:
Error: Expected end of string, got '('
Даже на их странице querybuilder ничего нет. Вы хотите сказать мне, что лучший ORM для php не имеет функции random?
Комментарии:
1. Здесь и здесь приведены два примера из Doctrine 1.2. Я бы предположил, что нечто подобное сработало бы для Doctrine 2.
Ответ №1:
Метод OrderBy должен принимать поле песни для целей сортировки (например, ‘s.author’ или ‘s.title’), а не случайное значение. Даже если вы выбрали случайное поле для упорядочивания, например, произвольно выбрали одно в php, это будет совсем не случайным, потому что вы всегда будете получать первый результат по текущим критериям сортировки. Если в ваших песнях 8 полей, вы получите только 8 разных песен в результатах поиска, даже если у вас хранятся тысячи.
Вот предложение:
$qb1->select('s')
->from('MyEntitySong', 's')
->where('s.id <> ?1')
->setMaxResults(1)
->setParameters(array(1=>$current->id))
->setFirstResult($offset);
Здесь $offset может быть случайным значением, которое вы получаете в php с помощью функций rand () или mt_rand(). Конечно, $offset должно быть меньше общего количества песен. Это всего лишь предложение, есть много способов, которыми вы можете это сделать.
ИМХО, я думаю, Doctrine2 — это необычный ORM, и нет ничего более продвинутого, чем он. Я предполагаю, что вы прочитали раздел справочного руководства о построителе запросов, но я также предлагаю вам прочитать раздел о DQL, в котором объясняется, какие функции доступны в системе запросов Doctrine, и как вы можете создать свои собственные (!).
Комментарии:
1. Настолько необычно, что вы не можете просто ЗАКАЗАТЬ С помощью RAND ().
Ответ №2:
Вам нужно добавить пользовательскую функцию DQL RAND. Для платформы symfony2 вы могли бы просто добавить в config:
doctrine:
orm:
entity_managers:
default:
dql:
numeric_functions:
rand: DoctrineExtensionsQueryMysqlRand
И добавить к вам зависимости в 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 вам может понадобиться другой класс реализации.