Как легко выбрать случайные строки в Doctrine 2 (автономные или Symfony 2 и 3)

Либо для изучения чего-то нового, либо просто потому, что нам нужно выбрать случайные элементы, записи из таблицы в нашей базе данных, и у нас нет времени для реализации новой функции Doctrine (в данном случае Rand, которая не реализована в dql), это Задача может стать сложной, если мы не используем правильные функции.

В mySql вы можете использовать следующий код, чтобы легко выбирать случайные строки из таблицы:

SELECT column FROM table
ORDER BY RAND()
LIMIT 10

Но если вы используете DQL (Doctrine Query Language), это будет не так просто. Согласно документации, вы можете реализовать расширение доктрины и добавить инструкцию RAND к нашим запросам (в этой статье мы не будем обрабатывать это, потому что это другая история и другая головная боль), но мы решим эту проблему легко и быстро только с помощью пары линии вместо этого добавляют целые классы в наш проект.

Для нашего решения мы будем использовать оператор where IN и будем просто выполнять поиск по какому-либо термину (в данном случае ID или любое автоинкрементное поле, если в вашей таблице нет первичного ключа с автоинкрементным, вы должны реализовать расширение RAND из доктрины ) по случайным числам с простой функцией PHP.

В этом примере таблица, которую мы будем использовать, будет иметь автоинкрементное поле с именем id (которое имеет числовые значения …), чтобы извлечь случайные записи, нам нужно сначала создать функцию, которая возвращает случайные числа с заданным диапазоном (начальное значение , максимальное значение и количество), как следующее:

function UniqueRandomNumbersWithinRange($min, $max, $quantity) {
$numbers = range($min, $max);
shuffle($numbers);
return array_slice($numbers, 0, $quantity);
}

UniqueRandomNumbersWithinRange даст нам случайные числа между заданным диапазоном, эти числа будут использоваться для поиска случайных строк в нашей таблице с доктриной, подобной этой:

$em = $this->getDoctrine()->getManager();
$repo = $em->getRepository('mybundleBundle:TableName');
$quantity = 5; // We only want 5 rows (however think in increase this value if you have previously removed rows on the table)
// This is the number of rows in the database
// You can use another method according to your needs
$totalRowsTable = $repo->createQueryBuilder('a')->select('count(a.id)')->getQuery()->getSingleScalarResult();// This will be in this case 10 because i have 10 records on this table
$random_ids = UniqueRandomNumbersWithinRange(1,$totalRowsTable,$quantity);
// var_dump($random_ids);
// outputs for example:
// array(1,5,2,8,3);
$random_articles = $repo->createQueryBuilder('a')
->where('a.id IN (:ids)') // if is another field, change it
->setParameter('ids', $random_ids)
->setMaxResults(3)// Add this line if you want to give a limit to the records (if all the ids exists then you would like to give a limit)
->getQuery()
->getResult();

Предыдущая структура кода довольно проста, WHERE IN будет соответствовать строкам, идентификаторы которых находятся в $ random_ids (массив). Вы можете изменить метод, чтобы получить общее количество строк в вашей базе данных (или получить идентификатор последнего регистра в соответствии с использованием вашей таблицы), если вам нужно. Самая важная часть — это где в строке вы можете проверить случайные числа, чтобы увидеть, работает ли он, прежде чем реализовывать полное решение. Повеселись !

Ссылка на основную публикацию
Adblock
detector