2013-05-18 13 views
5

ho il seguente schema di database:Symfony2 Dottrina ottenere il prodotto casuale da una categoria

table 'products' 
id 
category_id 

e, naturalmente, un tavolo categoria, solo con un id.

I dati sembrano qualcosa di simile:

Products 
-------------------- 
| id | category_id | 
-------------------- 
| 0 | 1   | 
| 1 | 1   | 
| 2 | 1   | 
| 3 | 2   | 
| 4 | 2   | 
| 5 | 1   | 
-------------------- 

Vorrei selezionare una categoria (ad esempio, categoria 1), in modo da selezionare tutte le righe da quella categoria nella mia classe di prodotto-repository:

return $this 
    ->createQueryBuilder('u') 
    ->andWhere('u.category = :category') 
    ->setMaxResults(1) 
    ->setParameter('category', $category->getId()) 
    ->getQuery() 
    ->getSingleResult() 
; 

Come posso selezionare ora un prodotto casuale? Inoltre: è possibile risolvere questo tramite relazioni?

ho un rapporto OneToMany tra le entità "Categoria" e "Prodotto", così ho potuto anche ottenere tutti i prodotti tramite categoria-> getProducts() ...

Qualsiasi aiuto sarebbe veramente utile, grazie

risposta

12

È necessario prima contare il numero totale di prodotti, quindi generare un offset casuale per selezionare un prodotto casuale.

Questo dovrebbe iniziare:

$count = $this->createQueryBuilder('u') 
      ->select('COUNT(u)') 
      ->getQuery() 
      ->getSingleScalarResult(); 

E poi si può generare un numero casuale tra il 1 e il numero totale di righe.

return $this->createQueryBuilder('u') 
    ->where('u.category = :category') 
    ->setFirstResult(rand(0, $count - 1)) 
    ->setMaxResults(1) 
    ->setParameter('category', $category->getId()) 
    ->getQuery() 
    ->getSingleResult() 
; 

che si traduce in:

SELECT * FROM products WHERE category_id = ? LIMIT 1, {random offset} 
+0

caso 'getResult' sulla query conteggio non essere' getSingleScalarResult'? – Machiel

+0

So che questo frammento ha funzionato quando ho risposto, ma non ho toccato Doctrine da un po 'di tempo, quindi le cose potrebbero essere cambiate. –

+1

Ecco una funzione pronta per l'uso: https://gist.github.com/Thinkscape/124d658e4076421c0516 –

0

Usare questa funzione di supporto:

<?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() 
    ; 
} 

Esempio utilizzo:

$randomItem = getRandomDoctrineItem($em, 'Application\Entity\Post');