Marco de Mongodb Explain for Aggregation

118

¿Existe una función de explicación para el marco de agregación en MongoDB? No puedo verlo en la documentación.

Si no es así, ¿hay alguna otra forma de verificar cómo funciona una consulta dentro del marco de agregación?

Sé que con encontrarte solo hazlo

db.collection.find().explain()

Pero con el marco de agregación obtengo un error

db.collection.aggregate(
    { $project : { "Tags._id" : 1 }},
    { $unwind : "$Tags" },
    { $match: {$or: [{"Tags._id":"tag1"},{"Tags._id":"tag2"}]}},
    { 
        $group: 
        { 
            _id : { id: "$_id"},
            "count": { $sum:1 } 
        }
    },
    { $sort: {"count":-1}}
).explain()
SCB
fuente

Respuestas:

172

Comenzando con MongoDB versión 3.0, simplemente cambiando el orden de

collection.aggregate(...).explain()

a

collection.explain().aggregate(...)

le dará los resultados deseados (documentación aquí ).

Para versiones anteriores> = 2.6, deberá usar la explainopción para operaciones de canalización de agregación

explain:true

db.collection.aggregate([
    { $project : { "Tags._id" : 1 }},
    { $unwind : "$Tags" },
    { $match: {$or: [{"Tags._id":"tag1"},{"Tags._id":"tag2"}]}},
    { $group: { 
        _id : "$_id",
        count: { $sum:1 } 
    }},
    {$sort: {"count":-1}}
  ],
  {
    explain:true
  }
)

Una consideración importante con el Marco agregación es que un índice sólo se puede utilizar para recuperar los datos iniciales para una tubería (por ejemplo, el uso de $match, $sort, $geonearal comienzo de una tubería), así como la posterior $lookupy $graphLookupetapas. Una vez que los datos se han recuperado en la tubería de agregación para su procesamiento (por ejemplo, pasando por etapas como $project, $unwindy $group) la manipulación adicional estará en la memoria (posiblemente usando archivos temporales si la allowDiskUseopción está configurada).

Optimización de tuberías

En general, puede optimizar las canalizaciones de agregación mediante:

  • Iniciar una canalización con una $matchetapa para restringir el procesamiento a los documentos relevantes.
  • Asegurar las iniciales $match/ $sortetapas están soportados por un índice eficiente .
  • Filtrado de datos utilizando principios $match, $limity $skip.
  • Minimizar las etapas innecesarias y la manipulación de documentos (quizás reconsiderar su esquema si se requieren gimnasia de agregación complicada).
  • Aprovechando los operadores de agregación más nuevos si ha actualizado su servidor MongoDB. Por ejemplo, MongoDB 3.4 agregó muchas etapas y expresiones de agregación nuevas, incluida la compatibilidad para trabajar con matrices, cadenas y facetas.

También hay una serie de optimizaciones de canalización de agregación que ocurren automáticamente según la versión de su servidor MongoDB. Por ejemplo, las etapas adyacentes pueden fusionarse y / o reordenarse para mejorar la ejecución sin afectar los resultados de salida.

Limitaciones

Como en MongoDB 3.4, la explainopción Aggregation Framework proporciona información sobre cómo se procesa una canalización, pero no admite el mismo nivel de detalle que el executionStatsmodo de una find()consulta. Si está enfocado en optimizar la ejecución de la consulta inicial, probablemente le resultará beneficioso revisar la find().explain()consulta equivalente con executionStatso allPlansExecutionverbosidad .

Hay algunas solicitudes de funciones relevantes para ver / votar en el rastreador de problemas de MongoDB con respecto a estadísticas de ejecución más detalladas para ayudar a optimizar / perfilar las canalizaciones de agregación:

Stennie
fuente
Gracias por la información, veré si puedo hacer algún cambio.
SCB
¿No debería el $sortobjeto estar dentro de la matriz de canalización?
JohnnyHK
@JohnnyHK: Sí. Algunas personas amables están "corrigiendo" la respuesta incorrectamente :).
Stennie
Pero esto no está dando la "ejecuciónStats"
Kanagavelu Sugumar
1
@KanagaveluSugumar He actualizado la respuesta con una aclaración sobre las explainlimitaciones del Marco de agregación , así como solicitudes de funciones relevantes para estadísticas de ejecución adicionales.
Stennie
29

A partir de la versión 2.6.x, mongodb permite a los usuarios explicar con un marco de agregación .

Todo lo que necesita hacer es agregar explicar: verdadero

db.records.aggregate(
  [ ...your pipeline...],
  { explain: true }
)

Gracias a Rafa, sé que era posible hacerlo incluso en 2.4, pero solo a través runCommand(). Pero ahora también puede usar el agregado.

Salvador Dalí
fuente
5
En realidad, puede explicar los agregados db.collection.runCommand('aggregate', {pipeline: [PIPELINE], explain: true})desde MongoDB 2.2.
Rafa
1
Tiene razón, en 2.2 y 2.4 solo puede explicar los agregados a través de runCommand. Gracias por el voto a favor.
Rafa
3
Si bien la opción existe técnicamente a través de runCommand antes de 2.6, no se garantiza que produzca resultados correctos y no debe recomendarse. Realmente solo debería usar esto en 2.5.3 o más reciente (y espere que todavía haya algunos errores al acecho antes de la versión de producción 2.6).
Stennie
20

El marco de agregación

El marco de agregación es un conjunto de herramientas de análisis MongoDBque nos permite ejecutar varios tipos de informes o análisis de documentos en una o más colecciones. Basado en la idea de una tubería. Tomamos las entradas de una MongoDBcolección y pasamos los documentos de esa colección a través de una o más etapas, cada una de las cuales realiza una operación diferente en sus entradas. Cada etapa toma como entrada cualquier etapa anterior a la que produjo como salida. Y las entradas y salidas de todas las etapas son un flujo de documentos. Cada etapa tiene un trabajo específico que hace. Espera una forma específica de documento y produce una salida específica, que en sí misma es un flujo de documentos. Al final de la canalización, tenemos acceso a la salida.

etapa del marco de agregación

Una etapa individual es una unidad de procesamiento de datos. Cada etapa toma como entrada un flujo de documentos uno a la vez, procesa cada documento de uno en uno y produce el flujo de salida de documentos. De nuevo, uno a la vez. Cada etapa proporciona un conjunto de perillas o regulables que podemos controlar para parametrizar la etapa para realizar cualquier tarea que nos interese hacer. Entonces, una etapa realiza una tarea genérica, una tarea de propósito general de algún tipo y parametriza la etapa para el conjunto particular de documentos con los que estamos trabajando. Y exactamente qué nos gustaría que hiciera esa etapa con esos documentos. Estos optimizables generalmente toman la forma de operadores que podemos proporcionar que modificarán campos, realizarán operaciones aritméticas, remodelarán documentos o realizarán algún tipo de tarea de acumulación, así como una variedad de otras cosas. Muchas veces, es el caso que '

mismo tipo de etapa varias veces dentro de una sola tubería

Por ejemplo, es posible que deseemos realizar un filtro inicial para no tener que pasar toda la colección a nuestra canalización. Pero, más adelante, después de un procesamiento adicional, desea filtrar una vez más utilizando un conjunto diferente de criterios. Entonces, para recapitular, la canalización funciona con una MongoDBcolección. Están compuestos por etapas, cada una de las cuales realiza una tarea de procesamiento de datos diferente en su entrada y produce documentos como salida para pasar a la siguiente etapa. Y finalmente, al final de la canalización, se produce la salida que luego podemos hacer algo dentro de nuestra aplicación. En muchos casos, es necesario incluir el mismo tipo de etapa, varias veces dentro de una canalización individual.

Zameer
fuente
gracias, fue útil para obtener una mejor comprensión.
Arun Pratap Singh