У меня есть следующая схема базы данных:
table 'products' id category_id
и, конечно же, таблицу категорий, только с идентификатором.
Данные выглядят примерно так:
Products -------------------- | id | category_id | -------------------- | 0 | 1 | | 1 | 1 | | 2 | 1 | | 3 | 2 | | 4 | 2 | | 5 | 1 | --------------------
Я хотел бы выбрать категорию (например, категорию 1), поэтому я выбираю все строки из этой категории в классе продукта-репозитория:
return $this ->createQueryBuilder('u') ->andWhere('u.category = :category') ->setMaxResults(1) ->setParameter('category', $category->getId()) ->getQuery() ->getSingleResult() ;
Как я могу выбрать сейчас случайный продукт? Также: возможно ли это решить через отношения?
У меня есть отношение OneToMany между объектами «Категория» и «Продукт», поэтому я мог бы также получить все продукты через категорию-> getProducts () …
Любая помощь была бы действительно полезной, спасибо
Сначала вам нужно подсчитать общее количество продуктов, а затем создать случайное смещение для выбора случайного продукта.
Это должно помочь вам начать:
$count = $this->createQueryBuilder('u') ->select('COUNT(u)') ->getQuery() ->getSingleScalarResult();
И тогда вы можете создать случайное число между вашим 1 и общим количеством строк.
return $this->createQueryBuilder('u') ->where('u.category = :category') ->setFirstResult(rand(0, $count - 1)) ->setMaxResults(1) ->setParameter('category', $category->getId()) ->getQuery() ->getSingleResult() ;
Что означает:
SELECT * FROM products WHERE category_id = ? LIMIT 1, {random offset}
Используйте эту вспомогательную функцию:
<?php use Doctrine\ORM\EntityManager; /** * Retrieve one random item of given class from ORM repository. * * @param EntityManager $em The Entity Manager instance to use * @param string $class The class name to retrieve items from * @return object */ function getRandomDoctrineItem(EntityManager $em, $class) { static $counters = []; if (!isset($counters[$class])) { $this->counters[$class] = (int) $this->manager->createQuery( 'SELECT COUNT(c) FROM '. $class .' c' )->getSingleScalarResult(); } return $em ->createQuery('SELECT c FROM ' . $class .' c ORDER BY c.id ASC') ->setMaxResults(1) ->setFirstResult(mt_rand(0, $counters[$class] - 1)) ->getSingleResult() ; }
Пример использования:
$randomItem = getRandomDoctrineItem($em, 'Application\Entity\Post');