D Agregacion hf16AHXv
D Agregacion hf16AHXv
D Agregacion hf16AHXv
Esquema
1-Introducción y objetivos
2-Conceptos
3-Map-Reduce
4-Aggregation Framework
5-Casos prácticos
Bibliografía
Lesson 1 of 7
Esquema
Lesson 2 of 7
1-Introducción y objetivos
funcionalidades que tiene MongoDB para llevarlo a cabo. La lectura de las Ideas claves te ayudará
a conocer lasintaxis de los comandos utilizados para realizar la agregación de datos.
MongoDB permite agregar los datos de una colección a través de operaciones como sumar,
contar y otros. A lo largo de este tema, se estudiarán los conceptos básicos de agregación y los
dos métodos que utiliza MongoDB para agregardatos: Map- Reduce y, a partir de la versión 2.2,
Aggregate. En especial, se estudiará el segundo por su importancia actual.
Los objetivos que se buscan alcanzar con este tema son los siguientes:
- Diferenciar los métodos y saber aplicar uno u otro en función del caso de uso.
2-Conceptos
4.2 Conceptos
Cualquier persona que trabaje con bases de datos tiene que realizar con frecuencia
consultas para agrupar datos y obtener resultados a partir de ellas. Por ejemplo, si se quiere
conocer la suma total deventas que cada comercial de una empresa ha conseguido en un año, es
necesario sumar cada una de las ventas quese han hecho por comercial y agruparlas por el
nombre de ese comercial.
Al final, se obtiene una tabla en la que aparecen η comerciales con la suma de sus ventas en el
período marcado en laconsulta, que en este caso sería de un año.
En las bases de datos relacionales, este tipo de consultas se realizan con el operador group by
(paraagrupar) y sum, count, etc. para realizar cualquier operación con sus datos. MongoDB
dispone de tresmétodos para gestionar la agregación: Map-Reduce, Aggregation Framework y
operadores simples de agregación específicos.
Por el contrario, MongoDB incorporó a partir de su versión 2.2 Aggregation Framework, para
poder realizar lasmismas opciones de agregación que se hacen en los lenguajes SQL
relacionales.
Aunque Map-Reduce es mucho más potente, ya que se tiene todo un lenguaje de programación
para realizarcálculos y generar salidas, también es más difícil de utilizar, por lo que es más
recomendable utilizar AggregationFramework para realizar cálculos sencillos.
Otra de las causas por la que se recomienda más utilizar Aggregation Framework es porque en
temas de rendimiento está mucho más optimizado y, por lo tanto, el tiempo de la consulta suele
sermucho menor.
Además de los dos modelos de agregación, MongoDB proporciona dos operadores simples que
no pueden incluirsedentro de los métodos de agregación descritos: count y distinct. El primero
cuenta el número de resultadosobtenidos a partir de la búsqueda y el segundo muestra los
resultados que son distintos del campo que se especifiquecomo parámetro. A continuación, se
puede ver el formato de distinct:
db.collection.distinct(, {})
Donde el atributo es el campo donde se hace el distinct y el filtro, los parámetros de la búsqueda.
Un ejemplo realsería:
3-Map-Reduce
4.3. Map-Reduce
Las operaciones de map-reduce tienen dos fases:
Una etapa de map que procesa cada documento y emite uno o más objetos para cada
documento de entrada.
modificaciones finales al resultado. También puede especificar una condición de consulta para s
eleccionar los documentos de entrada, así como ordenar y limitar los resultados.
Map-Reduce utiliza funciones de JavaScript personalizadas para realizar el map y el reduce de las
operaciones,así como la operación de finalización opcional. El uso de JavaScript proporciona una gran
flexibilidad encomparación con las pipelines, pero Map-Reduce es menos eficiente y más complejo.
db..mapReduce(, , )
El método Map-Reduce hace uso de una función map, la cual procesa un conjunto de
documentos y, mediante elcomando emit, retorna un par clave-valor, utilizando los atributos de
cada documento. Todos los valores de cada parclave-valor son agrupados de forma en que cada
clave tendrá asociado un array con los valores apropiados.
La función reduce recibe la clave y el array de valores como primer y segundo argumento
respectivamente; latarea de esta función es realizar operaciones de agregación sobre los valores
del array y retornar el valor resultante. Este valor será asociado a la clave respectiva.
query: permite definir las condiciones de búsqueda para filtrar los documentos que serán
procesados.
sort: indica la forma en la que se ordenarán los documentos antes de ser procesados, lo
cual permite optimizar el proceso.
finalize: es una función opcional a aplicar sobre los documentos retornados por la función
reduce.
scope: indica variables globales que serán accesibles desde las funciones map, reduce y
finalize.
jsMode: valor booleano para indicar si los documentos deben convertirse a formato JSON
en vez de BSON entre las funciones map y reduce. Por defecto es false.
verbose: valor booleano que indica si se debe mostrar información sobre el tiempo de
procesado de la función Map-Reduce. El valor por defecto es true. La
siguiente captura muestra un ejemplo de ejecución del comando mapReduce para calcular
la suma los precios de todoslos documentos en la collection productos.
{
_id: ObjectId("50a8240b927d5d8b5891743c"), cust_id: "abc123",
ord_date: new Date("Oct 04, 2012"), status: 'A',
price: 25,
items: [ { sku: "mmm", qty: 5, price: 2.5 },
{ sku: "nnn", qty: 5, price: 2.5 } ]
}
Por cada elemento, la función asocia sku con el nuevo objeto value q
ue contiene el
campo count a 1 y el elemento qty para el perdido, y emite el par
sku-value.
4-Aggregation Framework
Las etapas más básicas proporcionan filtros que funcionan como consultas y transformaciones
de documentosque modifican la forma del documento de salida.
db.coches.aggregate( [
db.collection.aggregate( [ { }, { }, ... ] )
Literal: $literal.
5-Casos prácticos
Los datos del primer y segundo caso no son iguales a los datos propuestos para el tercer caso.
db.norders.insertMany([
{ _id: 1, cust_id: "Ant O. Knee", ord_date: new Date("2020-03-01"), price: 25,
items:
[ { sku: "oranges", qty: 5, price: 2.5 }, { sku: "apples", qty: 5, price: 2.5 } ], status:
"A" },
[ { sku: "oranges", qty: 8, price: 2.5 }, { sku: "chocolates", qty: 5, price: 10 } ], stat
us: "A" },
[ { sku: "oranges", qty: 10, price: 2.5 }, { sku: "pears", qty: 10, price: 2.5 } ], status
: "A" },
[ { sku: "carrots", qty: 10, price: 1.0 }, { sku: "apples", qty: 10, price: 2.5 } ], status
: "A" },
{ _id: 7, cust_id: "Cam Elot", ord_date: new Date("2020-03-20"), price: 25,
items: [ { sku: "oranges", qty: 10, price: 2.5 } ], status: "A" },
{ _id: 8, cust_id: "Don Quis", ord_date: new Date("2020-03-20"), price: 75, items:
[ { sku: "chocolates", qty: 5, price: 10 }, { sku: "apples", qty: 10, price: 2.5 } ], status: "A" },
{ _id: 10, cust_id: "Don Quis", ord_date: new Date("2020-03-23"), price: 25, items: [ { sku:
"oranges", qty: 10, price: 2.5 } ], status: "A" }
])
db.map_reduce_example.find().sort({_id:1}) {
"_id" : "Ant O. Knee", "value" : 95 } { "_id" :
"Busby Bee", "value" : 125 } { "_id" : "Cam
Elot", "value" : 60 } { "_id" : "Don Quis",
"value" : 155 }
db.norders.aggregate([ {
$group: { _id: "$cust_id", value: { $sum: "$price" } } }, { $out:
"agg_alternative_1" ])
db.agg_alternative_1.find().sort({_id:1})
db.map_reduce_example2.find().sort( { _id: 1 } )
db.agg_alternative_3.find().sort( { _id: 1 } )
db.usersessions.insertMany([ {
userid: "a", start: ISODate('2020-03-03 14:17:00'), length: 95 } {
userid: "b", start: ISODate('2020-03-03 14:23:00'), length: 110}, {
userid: "c", start: ISODate('2020-03-03 15:02:00'), length: 120}, {
userid: "d", start: ISODate('2020-03-03 16:45:00'), length: 45 }, {
userid: "a", start: ISODate('2020-03-04 11:05:00'), length: 105}, {
userid: "b", start: ISODate('2020-03-04 13:14:00'), length: 120}, {
userid: "c", start: ISODate('2020-03-04 17:00:00'), length: 130}, {
userid: "d", start: ISODate('2020-03-04 15:37:00'), length: 65 } ])
db.usersessions.insertMany([
{ userid: "a", ts: ISODate('2020-03-05
14:17:00'), length: 130 }, { userid: "b", ts: ISODate('2020-03-05
14:23:00'), length: 40 }, { userid: "c", ts: ISODate('2020-03-05
15:02:00'), length: 110 }, { userid: "d", ts: ISODate('2020-03-05
16:45:00'), length: 100 } ])
};
var finalizeFunction = function(key,
reducedValue) { if (reducedValue.count > 0)
reducedValue.avg_time = reducedValue.total_time / reducedValue.count; return
reducedValue; };
db.usersessions.mapReduce( mapFunction,
reduceFunction,
{
out:
"session_stats", finalize: finalizeFunction
}
)
db.session_stats.find().sort( { _id: 1 } )
db.session_stats.find().sort( { _id: 1 } )
db.usersessions.drop(); db.usersessions.insertMany([ {
userid: "a", start:ISODate('2020-03-03 14:17:00'), length: 95 }, {
userid: "b", start:ISODate('2020-03-03 14:23:00'), length: 110 }, {
userid: "c", start:ISODate('2020-03-03 15:02:00'), length: 120 }, {
userid: "d", start:ISODate('2020-03-03 16:45:00'), length: 45 }, {
userid: "a", start:ISODate('2020-03-04 11:05:00'), length: 105 }, {
userid: "b", start:ISODate('2020-03-04 13:14:00'), length: 120 },
{ userid: "c", start:ISODate('2020-03-04 17:00:00'), length: 130 },
{ userid: "d", start:ISODate('2020-03-04 15:37:00'), length: 65 } ])
db.usersessions.aggregate([
{ $group: {_id: "$userid", total_time:
{$sum: "$length" }, count: {$sum: 1 }, avg_time: {$avg: "$length" }}},
{ $project: { value: { total_time: "$total_time",
count: "$count", avg_time: "$avg_time" } } },
{ $merge: {
into: "session_stats_agg", whenMatched: [ { $set: {
"value.total_time": {$add: ["$value.total_time", "$$new.value.total_time" ] }, "value.count":
{$add: ["$value.count", "$$new.value.count" ]}, "value.avg": {$divide:
[{$add: ["$value.total_time", "$$new.value.total_time"]}, {$add: ["$value.count",
"$$new.value.count" ] } ] } } } ],
whenNotMatched: "insert"
}}
])
db.session_stats_agg.find().sort( { _id: 1 } )
Bibliografía
Bibliografía
Bradshaw, S., Brazil, E., y Chodorow, K. (2019). MongoDB: the definitive guide:
Castillo, J. N., Garcés, J. R., Navas, M. P., Segovia, D. F. J., y Naranjo, J. E. A. (2017). Base de Datos
NoSQL:MongoDB vs. Cassandra en operaciones CRUD (Create, Read, Update, Delete). Revista
Publicando, 4(11 (1)), pp. 79-107.
Giamas, A. (2017). Mastering MongoDB 3.x: an expert's guide to building fault- tolerant
MongoDB applications.Packt Publishing.
Tiwari, S. (2011). Professional NoSQL (pp. 97-135, 217-232). John Wiley & Sons.