Este foro ya no está activo, así que no puedes publicar nuevas preguntas ni responder a las preguntas existentes.

DQL con count

4 de marzo de 2014

Hola, estoy haciendo una consulta que obtiene los artículos y el número de comentarios que tiene cada artículo de esta forma:

public function findArticulosAndNComentarios()
{
    $em = $this->getEntityManager();
 
    $dql = 'SELECT a AS articulo, COUNT(c.id) AS nComentarios
            FROM MiniBlogBundle:Articulo a
            LEFT JOIN MiniBlogBundle:Comentario c
            WHERE c.articulo = a.id
            GROUP BY a
            ORDER BY a.fechaCreacion';
 
    $query = $em->createQuery($dql);
 
    return $query->getResult();
}

Y en twig lo muestro de esta forma:

{% for fila in articulos %}
    {% set articulo = fila['articulo'] %}
    {% set comentarios = fila['nComentarios'] %}
{% endfor %}

Como veis en la consulta he tenido que poner un nombre para artículos para así no tener que poner en twig fila['0']. Mi pregunta es más bien si esta es la forma que hay de hacer esto o existe otra manera más clara y mejor.

Un saludo.


Respuestas

#1

Tal y como se explica en la sección "Pure and Mixed Results" del manual de Doctrine, existen dos tipos de resultados para las consultas DQL: resultados puros y resultados mixtos.

Los resultados puros son los que obtienes con la mayoría de consultas DQL y te permiten crear plantillas muy concisas, ya que la estructura de los resultados es la siguiente:

array
    [0] => Objeto
    [1] => Objeto
    [2] => Objeto
    ...

Si en la consultas añades un valor agregado (como en tu caso por ejemplo COUNT(c.id)) o un valor que no pertenezca a la entidad que estás consultando, entonces obtienes resultados mixtos, que tienen la siguiente estructura:

array
    [0]
        [0] => Objeto
        [1] => Valor agregado
    [1]
        [0] => Objeto
        [1] => Valor agregado
    [2]
        [0] => Objeto
        [1] => Valor agregado
    ...

Si realmente quieres simplificar tus plantillas, puedes reeemplazar el método getResult() de la consulta por getScalarResult(). Si lo haces, la estructura de los resultados será la siguiente:

array
    [0] array
        [a_id] => ...
        [a_titulo] => ...
        [a_contenido] => ...
        ...
        [nComentarios] => ...
    [1] array
        [a_id] => ...
        [a_titulo] => ...
        [a_contenido] => ...
        ...
        [nComentarios] => ...
    ...

Ten en cuenta que si utilizas el método getScalarResult(), lo que obtienes son simples arrays y no objetos hidratados, por lo que no podrás utilizar el lazy loading de Doctrine2 y muchas otras de sus características más interesantes.

@javiereguiluz

4 marzo 2014, 23:03
#2

Hola, gracias por tu gran respuesta. Por lo que veo entonces, la mejor opción es como lo he hecho ya que si no, pierdo funciones de Doctrine.

Un saludo

@AlbertoVioque

5 marzo 2014, 8:53