2011-06-05 26 views
7

Hasta ahora tengo:Cómo recuperar una fila aleatoria mediante Doctrine2 querybuilder?

$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)); 

Pero Doctrine2 no entiende que:

Error: Expected end of string, got '(' 

Ni siquiera su página QueryBuilder tiene nada en ella. ¿Quieres decirme que el mejor ORM para php no tiene una función aleatoria?

+1

[Aquí] (http://www.doctrine-project.org/documentation/manual/1_2/hu/dql-doctrine-query-language:order-by-clause:using-random-order) y [aquí] (http://www.onepie.org/2009/12/21/fetch-a-random-record-with-doctrine/) son dos ejemplos en Doctrine 1.2. Supongo que algo similar funcionaría para Doctrine 2. –

Respuesta

10

El método orderBy debe aceptar un campo de Song para fines de clasificación (como 's.author' o 's.title'), y no un valor aleatorio. Incluso si elige un campo aleatorio para ordenar, como seleccionar uno aleatoriamente en php, esto no será muy aleatorio, porque siempre obtendrá el primer resultado para los criterios de clasificación actuales. Si sus canciones tienen 8 campos, solo obtendrá 8 canciones diferentes en los resultados de búsqueda, incluso si tiene miles almacenados.

Aquí es una sugerencia:

$qb1->select('s') 
    ->from('\My\Entity\Song', 's') 
    ->where('s.id <> ?1') 
    ->setMaxResults(1) 
    ->setParameters(array(1=>$current->id)) 
    ->setFirstResult($offset); 

Aquí, $ desplazamiento puede ser un valor aleatorio que obtenga en php a través de rand() o() mt_rand funciones. Por supuesto, $ offset debe ser menor que el número total de canciones. Esta es solo una sugerencia, hay muchas maneras en que puede lograr esto.

EN MI OPINIÓN Creo que Doctrine2 es un ORM extraordinario, y no hay nada tan avanzado como él. Supongo que leyó la sección Query Builder de la guía de referencia, pero también sugiero que lea la sección DQL, que explica cuáles son las funciones disponibles en el sistema de consulta de Doctrine y cómo puede crear la suya (!).

+0

Tan extraordinario que no puedes simplemente ORDER BY RAND(). – darkbluesun

3

Debe agregar la función DQL personalizada RAND. Para plataforma Symfony2 simplemente puede añadir en config:

doctrine: 
    orm: 
     entity_managers: 
      default: 
       dql: 
        numeric_functions: 
         rand: DoctrineExtensions\Query\Mysql\Rand 

y añadir a que las dependencias en composer.json:

composer require beberlei/DoctrineExtensions

Entonces, la solución para conseguir 100 AcmeBundle:Item entidades azar sería tan sencillo como:

$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(); 

Nota: esto supone que estés useing MySQL o r MariaeB backend. Para SQLite o PostGreSQL puede necesitar una clase de implementación diferente.

+1

esto definitivamente debería ser la respuesta correcta –

Cuestiones relacionadas