7

tengo un grande de la consulta (en mi generador de consultas) y un montón de izquierda se une. Así que recibo artículos con sus comentarios y etiquetas, etc. Digamos que tengo el siguiente DQL:Doctrine2: La limitación de la izquierda se une a/paginación - Mejor Práctica

$dql = 'SELECT blogpost, comment, tags 
FROM BlogPost blogpost 
LEFT JOIN blogpost.comments comments 
LEFT JOIN blogpost.tags tags'; 

Ahora vamos a decir que mi base de datos tiene más de 100 entradas del blog, pero sólo quiero los primeros 10, pero con todos los comentarios de los 10 y todas sus etiquetas, si es que existen . Si uso setMaxResults, limita las Filas. Así que podría obtener las dos primeras publicaciones, pero a la última de ellas les faltan algunos de sus comentarios o etiquetas. Entonces el followin no funciona.

$result = $em->createQuery($dql)->setMaxResults(15)->getResult(); 

Utilizando el apenas documentado Pagination solución que se incluye con doctrine2.2 no funciona muy bien para mí tampoco, ya que es tan lento, pude así cargar todos los datos.

probé las soluciones en el Stackoverflow Article, pero incluso que el artículo no está en ellos una mejor práctica y la solución presentada es extremadamente lento.

¿No hay una buena práctica sobre cómo hacer esto? ¿Nadie está utilizando Doctrine2.2 en el modo de producción?

+1

Agregue el código que tiene a su pregunta, tal vez incluso con resultados de ejemplo para mostrar lo que quiere y lo que está obteniendo. –

Respuesta

10

conseguir los resultados apropiados con una consulta de este tipo es problemático. Hay un tutorial en el sitio web de Doctrine que explica este problema.

Pagination

El tutorial es más acerca de la paginación en lugar de obtener los 5 mejores resultados, pero la idea general es que se necesita para hacer un "SELECT a.id distinto de los artículos a ... LÍMITE 5" en vez de un SELECTO normal. Es un poco más complicado que esto, pero los últimos 2 puntos en ese tutorial deberían ponerlo en el camino correcto.

Actualización:

El problema aquí no es la doctrina, o cualquier otro ORM. El problema radica directamente en que la base de datos puede devolver los resultados que está solicitando. Así es como funcionan las uniones.

Si un explique en la consulta, se le dará una respuesta más en profundidad de lo que está sucediendo. Sería una buena idea agregar los resultados de eso a su pregunta inicial.

Sobre la base de lo que se analiza en el artículo de paginación, parece que necesita al menos 2 consultas para obtener los resultados deseados. Agregar DISTINCT a una consulta tiene el potencial de ralentizar drásticamente su consulta, pero solo es realmente necesario si tiene uniones en ella. Puede escribir otra consulta que solo recupere las primeras 10 publicaciones ordenadas por fecha de creación, sin las uniones. Una vez que tenga los ID de esas 10 publicaciones, haga otra consulta con sus join, y una WHERE blogpost.id IN (...) ORDER BY blogpost.created. Este método debería ser mucho más eficiente.

SELECT 
    bp 
FROM 
    Blogpost bp 
ORDER BY 
    bp.created DESC 
LIMIT 10 

Dado que todo lo que importa en la primera consulta son los identificadores, se puede configurar para usar Doctrina escalar hidratación.

SELECT 
    bg 
FROM 
    Blogpost bp 
LEFT JOIN 
    bp.comments c 
LEFT JOIN 
    bp.tags t 
WHERE 
    bp.id IN (...) 
ORDER BY 
    bp.created DESC 

También podría hacerlo en una consulta utilizando una subconsulta correlacionada. El mito de que las subconsultas siempre son malas NO es cierto. A veces son más rápidos que las uniones. Deberá experimentar para descubrir cuál es la mejor solución para usted.

2

Editar a la luz de la cuestión aclarado:

Usted puede hacer lo que quiera en MySQL nativa utilizando una subconsulta en la cláusula como tal:

SELECT * FROM 
(SELECT * FROM articles ORDER BY date LIMIT 5) AS limited_articles, 
comments, 
tags 
WHERE 
limited_articles.article_id=comments.article_id 
limited_articles.article_id=tags.article_id 

Por lo que yo sé, DQL no admite subconsultas como esta, por lo que puede usar la clase NativeQuery.

+0

No, no quiero la M más reciente de mi N. Quiero la N más reciente con todas sus M, X e Y. –

+0

No soy un gran admirador de Usar un Marco DABL/ORM y seguir usando el lenguaje nativo Consultas. No tiene mucho sentido para mí. –

+1

Entonces parece que tendrá que hacer dos consultas. Estoy de acuerdo en que debería haber una mejor manera de limitar y publicar los resultados de las uniones. –

Cuestiones relacionadas