Costos en Aggregation Framework - Caso base

Costos en Aggregation Framework - Caso base

de Bruno Alberto Szilagyi Ibarra -
Número de respuestas: 8

Buenas, la verdad que nos está costando bastante el tema costos.
Desarrollamos una propuesta pero no sabemos si es correcta dado que computar el costo en el pipeline nos quedó bastante largo.

Queríamos preguntar primero por el caso base, un pipeline con solo un stage de proyección.

db['customer'].aggregate([
    {
        '$project': {
            '_id': 0,
            'ID': '$customer_id',
        }
    }
])

Este ejemplo nos parece que es equivalente a un select customer_id as ID from customer.
Acá entendemos que el costo es 1 por cada elemento de la colección de customers + 0.01 por cada uno por traer el atributo. Eso está ok?

Siguiendo las preguntas, si tenemos varios stages en el pipeline, los costos se deben calcular por cada stage y luego sumar al final o hay algún costo que podamos considerar ya se omite?

Espero se entiendan las dudas, muchas gracias.

En respuesta a Bruno Alberto Szilagyi Ibarra

Re: Costos en Aggregation Framework - Caso base

de Martin Giachino -
Tu ejemplo es correcto, diría que lo estás entendiendo perfectamente!

Cabe aclarar (por si otro compañero lee el mismo mensaje) que el costo de 1 es porque está utilizando el campo especial '_id' que es manejado por mongoDB y que tiene un índice creado y mantenido por mongoDB mismo.

Sobre el pipeline, también es correcto lo que dicen y el costo es ir concatenando los costos de cada etapa del pipeline.

Martín
En respuesta a Martin Giachino

Re: Costos en Aggregation Framework - Caso base

de Bruno Alberto Szilagyi Ibarra -

Perfecto Martin, muchas gracias.

Solo para seguir entendiendo, en el ejemplo base de arriba, no lo explique, pero entiendo que para recuperar todos los elementos de la colección se utiliza el índice creado por mongo y recorriendolo es que se recupera cada uno, es así?.

Si el tamaño de la colección de customers es N y teniendo en cuenta que recupero M atributos (sin contar el _id), la cuenta queda:
N (1 + 0.01 * M)

¿Correcto?

Muchas gracias!

En respuesta a Martin Giachino

Re: Costos en Aggregation Framework - Caso base

de Franco Enrique Fontana -

Hola, en este ejemplo estamos viendo algo que no nos cierra.

Martín dice que en la colección de customer, efectivamente está accediendo por índice "_id" al usar el campo "_id":0 en el stage $project.

La colección customer, tiene creado un índice de nombre "_id", pero entendemos que eso no quiere decir que la agregación lo use.

Si hacemos un explain del plan de ejecución de la agregación que Bruno propone (lo probamos sobre la colección), vemos que hace un "COLLSCAN" en el inputStage lo que quiere decir que se barre toda la colección. Por este motivo es que nos parece que el ejemplo no usa el índice "_id", y en general creo que no podemos decir que usa un índice si el explain de la consulta no nos da un "IXSCAN".

Abajo va la salida de la primera parte del explain para el ejemplo de Bruno.

Martín/Lorena, nos podrían aclarar esto ?.


"explainVersion" : "1",

"queryPlanner" : {

"namespace" : "FING_Sakila.customer",

"indexFilterSet" : false,

"parsedQuery" : {

},

"queryHash" : "2B4C9391",

"planCacheKey" : "2B4C9391",

"optimizedPipeline" : true,

"maxIndexedOrSolutionsReached" : false,

"maxIndexedAndSolutionsReached" : false,

"maxScansToExplodeReached" : false,

"winningPlan" : {

"stage" : "PROJECTION_DEFAULT",

"transformBy" : {

"_id" : true,

"ID" : "$customer_id"

},

"inputStage" : {

"stage" : "COLLSCAN",

"direction" : "forward"

}

},

"rejectedPlans" : [

]

},

"executionStats" : {

"executionSuccess" : true,

"nReturned" : 599,

"executionTimeMillis" : 1,

"totalKeysExamined" : 0,

"totalDocsExamined" : 599,


y sigue el explain  . . . . . . .


En respuesta a Franco Enrique Fontana

Re: Costos en Aggregation Framework - Caso base

de Martin Giachino -

Hola, volví a leer el mensaje con el pipeline original y el error fue mío. Venía leyendo otras dudas relacionadas a los find's o lookup's y respondí como si ésta también refería a una búsqueda, cuando en realidad es un project.

Entonces:

- yo respondí pensando en una búsqueda de un objeto por su id de mongo (_id), por el índice, en donde ahí sería costo 1. Esto es correcto pero no "matchea" con lo que realmente preguntó el compañero que era un project.

- dado que es un project, y el project trabaja sobre una colección (en este caso sobre customer completa) o sobre una colección resultado previo de otra etapa del pipeline (no sería este caso), y lo que hace es agregar/quitar campos ID a todos sus documentos (en este caso ID) no le queda otra que recorrer toda la colección (imagino que por eso ves el COLSCAN) e insertar el nuevo campo. También eso explica la cantidad de documentos que son inspeccionados en el stage (599) que se corresponden exactamente con la cantidad de documentos en la colección.

Martín

En respuesta a Martin Giachino

Re: Costos en Aggregation Framework - Caso base

de Bruno Alberto Szilagyi Ibarra -
Martin, buenas, no te entendí entonces. Tus respuestas a mis preguntas están erróneas, los costos que yo decía no se cumplen?
En respuesta a Bruno Alberto Szilagyi Ibarra

Re: Costos en Aggregation Framework - Caso base

de Martin Giachino -
Exacto, porque como dije "respondí como si ésta también refería a una búsqueda, cuando en realidad es un project".

En el caso puntual de tu "project" es simple, no tienes stage anterior que filtre nada, así que estás trabajando sobre la colección customer completa, y el proyect debe recorrerla toda agregando un campo nuevo en cada documento que se llena a su vez con otro. En definitiva debes tomar cada elemento de la colección (1) y por cada uno leer el campo $customer_id (0.01) y eventualmente podemos sumarle otro (0.01) para escribirlo.