MongoDB Agregación PDF
Document Details
Uploaded by Itan
Universidad Internacional de La Rioja
Tags
Summary
Este documento presenta un tutorial sobre la agregación de datos en MongoDB. Explora los conceptos básicos, los métodos Map-Reduce y Aggregation Framework, y proporciona ejemplos prácticos. Se centra en la funcionalidad y el uso de herramientas de agregación en MongoDB.
Full Transcript
Tema 4 Métodos de Captura y Almacenamiento de los Datos MongoDB: Agregación © Universidad Internacional de La Rioja (UNIR) Índice Esquema 3 Ideas clave 4 4.1. Introducción y objetivos 4 4.2. Conceptos 5 4.3. Map-Reduce 6 4.4. Aggregation Framework 12 4.5. Casos prácticos 19 A fondo 29 Test 32 Existe...
Tema 4 Métodos de Captura y Almacenamiento de los Datos MongoDB: Agregación © Universidad Internacional de La Rioja (UNIR) Índice Esquema 3 Ideas clave 4 4.1. Introducción y objetivos 4 4.2. Conceptos 5 4.3. Map-Reduce 6 4.4. Aggregation Framework 12 4.5. Casos prácticos 19 A fondo 29 Test 32 Existen operaciones especificas de agregación: count, distinct y group. Existen dos métodos de agregación en MongoDB: Map-Reduce y Aggregate. La mayor ventaja de la utilización de este método de agregación es la potencia que ofrece, ya que se pueden personalizar totalmente cada una de sus funciones. Los parámetros de agregación en la función Map-Reduce se especifican como un objeto JSOM. El lenguaje de programación utilizado es JavaScript. Map-Reduce está formada por dos funciones. Una función map que genera los pares clave-valor y otra reduce, que opera sobre ellos. Las funciones de agregación son útiles para agrupar datos y obtener resultados a partir de ellos. En la base de datos relacionales, este tipo de consultas se realizan con el operador group by ( para agrupar) y sum, count, etc., para realizar cualquier operación con sus datos. Map-Reduce AGREGACI ÓN Co ncepto © Universidad Internacional de La Rioja (UNIR) Además de los operadores de búsqueda, tiene muchos otros que hacen la vida mas fácil al trabajar, array, string, etc. Es obligatorio especificar el campo _id en el nuevo documento, ya que estos son los valores a agrupar. Las etapas mas usadas son la $mach, encargada de la búsqueda, y $group, la que agrupa y hace los cálculos. El framework de agregación está modelado en varias etapas que transforman los documentos en un resultado agregado. A g g re gation F ra m ewor k Esquema Métodos de Captura y Almacenamiento de los Datos Tema 4. Esquema 3 Ideas clave 4.1. Introducción y objetivos Este tema se enfoca en los conceptos básicos de agregación y las dos funcionalidades que tiene MongoDB para llevarlo a cabo. La lectura de las Ideas claves te ayudará a conocer la sintaxis de los comandos utilizados para realizar la agregación de datos. Al tratarse de un tema muy práctico, la mejor forma de estudiarlo es a través de la realización de los trabajos asignados. Además de los trabajos, es recomendable trabajar de forma proactiva con MongoDB, lo cual te ayudará a familiarizarte con el funcionamiento del sistema. 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 agregar datos: MapReduce y, a partir de la versión 2.2, Aggregate. En especial, se estudiará el segundo por su importancia actual. © Universidad Internacional de La Rioja (UNIR) Los objetivos que se buscan alcanzar con este tema son los siguientes: Comprender los métodos Map-Reduce y Aggregate. Diferenciar los métodos y saber aplicar uno u otro en función del caso de uso. Poner en práctica el uso de ambos métodos a través de ejercicios guiados. Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 4 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 de ventas que cada comercial de una empresa ha conseguido en un año, es necesario sumar cada una de las ventas que se 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 la consulta, 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 (para agrupar) y sum, count, etc. para realizar cualquier operación con sus datos. MongoDB dispone de tres métodos para gestionar la agregación: Map-Reduce, Aggregation Framework y operadores simples de agregación específicos. Map-Reduce es un modelo de programación utilizado por Google para el cálculo en paralelo de grandes volúmenes de datos. Debido a la incursión del big data, este modelo ha tomado mucha fuerza y se ha añadido a frameworks y tecnologías como MongoDB, Hadoop y muchas otras. Por el contrario, MongoDB incorporó a partir de su versión 2.2 Aggregation Framework, para poder realizar las mismas opciones de agregación que se hacen en los lenguajes SQL relacionales. © Universidad Internacional de La Rioja (UNIR) Aunque Map-Reduce es mucho más potente, ya que se tiene todo un lenguaje de programación para realizar cálculos y generar salidas, también es más difícil de utilizar, por lo que es más recomendable utilizar Aggregation Framework para realizar cálculos sencillos. Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 5 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 ser mucho menor. Además de los dos modelos de agregación, MongoDB proporciona dos operadores simples que no pueden incluirse dentro de los métodos de agregación descritos: count y distinct. El primero cuenta el número de resultados obtenidos a partir de la búsqueda y el segundo muestra los resultados que son distintos del campo que se especifique como 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 real sería: db.coches.distinct(“modelo”, {marca: “bmw”}). 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. © Universidad Internacional de La Rioja (UNIR) Una fase de reduce que combina la salida de la operación del map. Opcionalmente, Map-Reduce puede tener una etapa de finalización para realizar modificaciones finales al resultado. También puede especificar una condición de consulta para seleccionar los documentos de entrada, así como ordenar y limitar los resultados. Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 6 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 en comparación con las pipelines, pero Map-Reduce es menos eficiente y más complejo. En el siguiente recuadro se muestra la sintaxis del método Map-Reduce: db..mapReduce(, , ) El método Map-Reduce hace uso de una función map, la cual procesa un conjunto de documentos y, mediante el comando emit, retorna un par clave-valor, utilizando los atributos de cada documento. Todos los valores de cada par clave-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; la tarea 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. Los parámetros de agregación en la función Map-Reduce se especifican como un objeto JSON, con los siguientes atributos: © Universidad Internacional de La Rioja (UNIR) out: es el único atributo obligatorio. Indica el nombre de la collection donde se almacenará el resultado de la operación Map-Reduce. También puede indicarse la función retorne el resultado directamente, a través del objeto {inline: 1}. 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. Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 7 limit: indica el número máximo de documentos a retornar. 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 todos los documentos en la collection productos. Figura 1. Ejemplo de Map-Reduce en la consola de MongoDB. En el ejemplo, la función map emite pares clave-valor con la cadena de texto «Suma» © Universidad Internacional de La Rioja (UNIR) como clave constante y el atributo precio como el valor. La función reduce se encarga de sumar los valores del array de precios, y este valor se asigna a la clave «Suma» indicada previamente. Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 8 Además, se indica que la función retornará directamente los valores mediante el atributo inline. Los resultados del método Map-Reduce se pueden obtener como un array de documentos dentro del atributo results. En el siguiente ejemplo, se va realizar una operación Map-Reduce más compleja, en la colección de pedidos para todos los documentos que tengan un valor ord_date mayor que 01/01/2012. La operación agrupa por el campo item.sku y calcula el número de pedidos y la cantidad total para cada sku. La operación concluye calculando la cantidad media por pedido para cada valor de sku. Si se parte del siguiente formato de documento: { _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 } ] } La función map que procesa cada documento: En la función, this se refiere al documento que la operación Map-Reduce está procesando. Por cada elemento, la función asocia sku con el nuevo objeto value que contiene el © Universidad Internacional de La Rioja (UNIR) campo count a 1 y el elemento qty para el perdido, y emite el par sku-value. var mapFunction = function() { for (var idx = 0; idx < this.items.length; idx++) { var key = this.items[idx].sku; var value = { count: 1, Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 9 qty: this.items[idx].qty }; emit(key, value); } }; Se define la función reduce con dos argumentos: keySKU y countObjVals: CountObjVals es un array cuyos elementos son los objetos asignados a los valores de keySKU agrupados pasados por la función map a la función reduce. La función reduce la matriz countObjVals a un solo objeto reducedValue que contiene los campos count y qty. En reduceVal, el campo count contiene la suma de los campos count de los elementos individuales del array, y el campo qty contiene la suma de los campos qty de los elementos individuales del array: var reduceFunction = function(keySKU, countObjVals) { reducedVal = { count: 0, qty: 0 }; for (var idx = 0; idx < countObjVals.length; idx++) { reducedVal.count += countObjVals[idx].count; reducedVal.qty += countObjVals[idx].qty; } return reducedVal; }; Para terminar, se define una función de finalización con dos argumentos key y reduceVal. La función modifica el objeto reduceVal para agregar un campo © Universidad Internacional de La Rioja (UNIR) computado llamado avg y devuelve el objeto modificado: var finalizeFunction = function (key, reducedVal) { reducedVal.avg = reducedVal.qty/reducedVal.count; return reducedVal; }; Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 10 Para terminar, se realiza la operación de Map-Reduce en la colección utilizando todas las funciones anteriores: db.orders.mapReduce( mapFunction, reduceFunction, { out: { merge: "map_reduce_example" }, query:{ ord_date: { $gt: new Date('01/01/2012') } }, finalize: finalizeFunction }); Esta operación utiliza el campo de consulta para seleccionar solo aquellos documentos con ord_date mayor que la fecha 01/01/2012. Seguidamente, emite los resultados a una colección map_reduce_example. Si ya existe la colección map_reduce_example, la operación combinará el contenido existente con los resultados de esta operación. Ten en cuenta que: A partir de MongoDB 2.4, ciertas funciones y propiedades de la consola son inaccesibles en las operaciones de reducción de mapas. MongoDB 2.4 también proporciona soporte para múltiples operaciones de JavaScript para ejecutarse al mismo tiempo. Antes de MongoDB 2.4, el código JavaScript se ejecutaba en un solo hilo, lo que generaba problemas de concurrencia para reducir el mapa. A partir de la versión 4.2, se depreca la opción de Map-Reduce para crear una nueva colección fragmentada, así como el uso de la opción de fragmentación para Map-Reduce. Para enviar a una colección fragmentada, crea primero la colección fragmentada. MongoDB 4.2 también depreca el reemplazo de una colección fragmentada existente y © Universidad Internacional de La Rioja (UNIR) la especificación explícita de nonAtomic: false. Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 11 4.4. Aggregation Framework El framework de agregación de MongoDB está modelado en el concepto de tuberías de procesamiento de datos, es decir, los documentos entran en una tubería (pipeline) de varias etapas que transforman los documentos en un resultado agregado. Las etapas más básicas proporcionan filtros que funcionan como consultas y transformaciones de documentos que modifican la forma del documento de salida. El resto de operaciones proporcionan herramientas para agrupar y clasificar documentos por campo o campos específicos, así como herramientas para agregar el contenido de arrays, incluyendo arrays de documentos. Además, las etapas pueden utilizar operadores para tareas tales como calcular el promedio o concatenación de cadenas. Aggregate funciona perfectamente con la capacidad de sharding que proporciona MongoDB y que se verá más adelante. Además, se puede utilizar índices para mejorar el rendimiento durante algunas de sus etapas. Independientemente, Aggregate tiene una fase de optimización interna, lo que le permite mejorar sustancialmente en rendimiento a Map-Reduce. A continuación, se ilustra el funcionamiento de Aggregate con un ejemplo básico: db.coches.aggregate( [ $match stage {$match: {marca: “BMW” } }, © Universidad Internacional de La Rioja (UNIR) $group stage {$group: {_id: “$modelo”, total: { $sum: “$precio”} } }, more stage {... }, more stage {... } ] ) Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 12 El funcionamiento en etapas sería el siguiente: { } { } { } { } marca: “BMW”, modelo: “X5”, precio: 40000 marca: “BMW”, modelo: “X3”, precio: 30000 { } $match marca: “BMW”, modelo: “X5”, precio: 45000 marca: “Audi”, modelo: “A5”, precio: 40000 { } { } marca: “BMW”, modelo: “X5”, precio: 40000 marca: “BMW”, modelo: “X3”, precio: 30000 { $group marca: “BMW”, modelo: “X5”, precio: 45000 } { } _id: “X5”, total: 85000 _id: “X3”, total: 30000 Figura 2. Ejemplo de agrupación con Aggregate en MongoDB. Como se puede ver, la etapa de filtrado ($match) es análoga a la vista en los filtros convencionales de MongoDB, por lo que esta operación busca los documentos según los valores especiados. Por otro lado, la etapa de agrupación ($group), que es quizá la más usada en el proceso de agrupación, permite agrupar y realizar los cálculos sobre los documentos. Nótese que es obligatorio especificar el campo _id en el nuevo documento, ya que estos son los valores a agrupar. Es posible definir agrupaciones para campos múltiples. Esta etapa trasforma el documento de salida, por lo que en ella se deben especificar, como se ha podido ver, © Universidad Internacional de La Rioja (UNIR) los nuevos atributos de la colección y cómo se obtienen estos atributos. MongoDB permite utilizar los siguientes operadores: $min: devuelve el valor mínimo de los valores numéricos. $max: devuelve el valor máximo de los valores numéricos. Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 13 $avg: devuelve el valor medio de los valores numéricos. $sum: calcula y devuelve la suma de los valores numéricos. $first: devuelve el valor que resulta de aplicar una expresión al primer documento de un grupo de documentos que comparten el mismo grupo por un campo. Solo tiene sentido cuando los documentos están en un orden definido. Un ejemplo de uso es en fechas. $last: devuelve el valor que resulta de aplicar una expresión al último documento de un grupo de documentos que comparten el mismo grupo por un campo. Solo tiene sentido cuando los documentos están en un orden definido. $addToSet: devuelve un array con todos los valores únicos que resulta de aplicar una expresión a cada documento de un grupo de documentos que comparten el mismo grupo por clave. El orden de los elementos en la matriz de salida no está especificado. $push: devuelve un array con todos los valores que resultan de la aplicación de una expresión a cada documento de un grupo de documentos que comparten el mismo grupo por clave. $stdDevPop: (desde la versión 3.4) calcula la desviación estándar de la población de los valores de entrada. Se debe utilizar si los valores abarcan toda la población de datos que desea representar y no porque se desee generalizar sobre una población © Universidad Internacional de La Rioja (UNIR) mayor. Omite valores no numéricos. $stdDevSamp: (desde la versión 3.4.) Calcula la desviación estándar de la muestra de los valores de entrada. Se debe utilizar si los valores abarcan una muestra de una población de datos a partir de la cual se generaliza sobre la población total. Omite valores no numéricos. Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 14 El framework de agregación permite definir un mayor número de etapas que las dos que se han descrito anteriormente. El esquema general, por lo tanto, es el siguiente: db.collection.aggregate( [ { }, { }, … ] ) A continuación, se detallan todas las etapas posibles: $collStats: devuelve estadísticas sobre una colección o una vista. $project: redimensiona cada documento en el flujo, por ejemplo, agregando nuevos campos o eliminando campos existentes. Para cada documento de entrada, se genera un documento. $match: filtra el flujo de documentos para permitir que solo los documentos coincidentes pasen sin modificaciones a la siguiente fase de la canalización. $redact: redimensiona cada documento en el flujo restringiendo el contenido de cada documento basado en la información almacenada en los propios documentos. Incorpora la funcionalidad de $project y $match. Puede utilizarse para implementar la redacción a nivel de campo. Para cada documento de entrada, genera uno o cero documentos. $limit: transmite los primeros 𝑛𝑛 documentos no modificados a la canalización donde 𝑛𝑛 es el límite especificado. Para cada documento de entrada, se obtiene un © Universidad Internacional de La Rioja (UNIR) documento (para los primeros 𝑛𝑛 documentos) o cero documentos (después de los primeros 𝑛𝑛 documentos). $skip: salta los primeros 𝑛𝑛 documentos donde 𝑛𝑛 es el número de salto especificado y pasa los documentos restantes sin modificar a la tubería. Para cada documento de entrada, se emiten documentos cero (para los primeros 𝑛𝑛 documentos) o un documento (después de los primeros 𝑛𝑛 documentos). Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 15 $unwind: deconstruye un campo de un array de los documentos de entrada para generar un documento para cada elemento. Cada documento de salida reemplaza el array con un valor de elemento. Para cada documento de entrada, se producen 𝑛𝑛 documentos donde 𝑛𝑛 es el número de elementos del array y puede ser cero para una matriz vacía. $group: agrupa los documentos de entrada por una expresión de identificador especificada y aplica la(s) expresión(es) acumuladora(s), si se especifica, a cada grupo. Consume todos los documentos de entrada y genera un documento por cada grupo distinto. Los documentos de salida solo contienen el campo identificador y, si se especifica, los campos acumulados. $sample: selecciona aleatoriamente el número especificado de documentos de su entrada. $sort: reordena el flujo de documentos mediante una clave de clasificación especificada. Solo cambia el orden; Los documentos permanecen sin modificar. Para cada documento de entrada, se genera un documento. $geoNear: devuelve un flujo ordenado de documentos basado en la proximidad a un punto geoespacial. Incorpora la funcionalidad de $match, $sort y $limit para los datos geoespaciales. Los documentos de salida incluyen un campo de distancia adicional y pueden incluir un campo de identificador de ubicación. $lookup: realiza una combinación externa izquierda con otra colección en la misma © Universidad Internacional de La Rioja (UNIR) base de datos para filtrar en documentos de la colección «unida» para su procesamiento. $out: escribe los documentos resultantes de la tubería de agregación en una colección. Para usar la etapa $out, debe ser la última etapa en la tubería. $indexStats: devuelve estadísticas sobre el uso de cada índice para la colección. Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 16 $facet: procesa múltiples tuberías de agregación dentro de una sola etapa en el mismo conjunto de documentos de entrada. Permite la creación de agregaciones multifacéticas capaces de caracterizar datos a través de múltiples dimensiones, o facetas, en una sola etapa. $bucket: categoriza los documentos entrantes en grupos, llamados cubos, basados en una expresión especificada y límites de cubo. $bucketAuto: clasifica los documentos entrantes en un número específico de grupos, llamados cubos, en función de una expresión especificada. Los límites del cubo se determinan automáticamente en un intento de distribuir uniformemente los documentos en el número especificado de cubos. $sortByCount: agrupa los documentos entrantes basados en el valor de una expresión especificada y, a continuación, calcula el recuento de documentos en cada grupo distinto. $addFields: agrega nuevos campos a los documentos. Produce documentos que contienen todos los campos existentes de los documentos de entrada y campos añadidos recientemente. $replaceRoot: reemplaza un documento con el documento incrustado especificado. La operación reemplaza todos los campos existentes en el documento de entrada, incluido el campo _id. Especifica un documento incrustado en el documento de © Universidad Internacional de La Rioja (UNIR) entrada para promocionar el documento incrustado al nivel superior. $count: devuelve un recuento del número de documentos en esta etapa de la canalización de agregación. $graphLookup: realiza una búsqueda recursiva en una colección. A cada documento de salida, agrega un nuevo campo de matriz que contiene los resultados de recorrido de la búsqueda recursiva para ese documento. Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 17 Los operadores de expresión se construyen para construir expresiones en algunas de las etapas de la tubería. Algunos de ellos ya se han visto en el tema anterior. El formato es el siguiente: {: [ , , … ]} A continuación, se enumera cada tipo de operador: Booleanos: $and, $or, $not. De conjunto: $setEquals, $setIntersection, $setUnin, $setDifference, $setIsSubset, $anyElmenetTrue, $allElementsTrue. De comparación: $cmp, $eq, $gt, $gte, $lt, $lte, $ne. Aritméticos: $abs, $add, $ceil, $divide, $exp, $floor, $ln, $log, $log10, $mod, $multiply, $pow, $sqrt, $subtract, $truc. De cadena de caracteres: $concat, $indexOfBytes, $indexOfCP, $split, $strLenBytes, $strLenCP, $strcasecmp, $substr, $substrBytes, $substrCP, $toLower, $toUpper. Búsqueda de texto: $meta. Array: $arrayElemAt, $concatArrays, $filter, $indexOfArray, $isArray, $range, © Universidad Internacional de La Rioja (UNIR) $reverseArray, $reduce, $size, $slice, $zip, $in. Variable: $map, $let. Literal: $literal. Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 18 Date: $dayOfYear, $dayOfMonth, $dayOfWeek, $year, $month, $week, $hour, $minute, $second, $millisecond, $dateToString, $isoDayOfWeek, $isoWeek, $isoWeekYear. Condicional: $cond, $ifNull, $switch. Tipo de datos: $type. 4.5. Casos prácticos En este apartado pondrás en práctica lo aprendido con el método Map-Reduce y lo compararás con las funciones de Aggregate. Se proponen tres casos prácticos donde debes: 1. Insertar los datos. 2. Crear las funciones Map-Reduce. 3. Escribir la función Aggregate. 4. Finalmente, consultar el documento de salida de las operaciones anteriores. Los datos del primer y segundo caso no son iguales a los datos propuestos para el © Universidad Internacional de La Rioja (UNIR) tercer caso. Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 19 Caso 1: usar Map-Reduce y comparar con Aggregate Para los siguientes ejercicios, utiliza el siguiente conjunto de documentos de la colección norders. 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" }, { _id: 2, cust_id: "Ant O. Knee", ord_date: new Date("2020-03-08"), price: 70, items: [ { sku: "oranges", qty: 8, price: 2.5 }, { sku: "chocolates", qty: 5, price: 10 } ], status: "A" }, { _id: 3, cust_id: "Busby Bee", ord_date: new Date("2020-03-08"), price: 50, items: [ { sku: "oranges", qty: 10, price: 2.5 }, { sku: "pears", qty: 10, price: 2.5 } ], status: "A" }, { _id: 4, cust_id: "Busby Bee", ord_date: new Date("2020-03-18"), price: 25, items: [ { sku: "oranges", qty: 10, price: 2.5 } ], status: "A" }, { _id: 5, cust_id: "Busby Bee", ord_date: new Date("2020-03-19"), price: 50, items: [ { sku: "chocolates", qty: 5, price: 10 } ], status: "A"}, { _id: 6, cust_id: "Cam Elot", ord_date: new Date("2020-03-19"), price: 35, items: [ { 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: 9, cust_id: "Don Quis", ord_date: new Date("2020-03-20"), price: 55, items: [ { sku: "carrots", qty: 5, price: 1.0 }, { sku: "apples", qty: 10, price: 2.5 }, { sku: "oranges", qty: 10, price: 2.5 } ], status: "A" }, © Universidad Internacional de La Rioja (UNIR) { _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" } ]) Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 20 Escribe las siguientes funciones: var mapFunction1 = function() { emit(this.cust_id, this.price); }; var reduceFunction1 = function(keyCustId, valuesPrices) { return Array.sum(valuesPrices); }; Ahora aplica las funciones sobre los documentos anteriores: db.norders.mapReduce( mapFunction1, reduceFunction1, { out: "map_reduce_example" } ) Observa que el resultado de Map-Reduce se almacena en una nueva colección llamada map_reduce_example. El paso siguiente es ejecutar una consulta sobre esta nueva colección. 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 } © Universidad Internacional de La Rioja (UNIR) Ahora realiza la misma operación anterior, pero utilizando la función aggregate. db.norders.aggregate([ { $group: { _id: "$cust_id", value: { $sum: "$price" } } }, { $out: "agg_alternative_1" } ]) Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 21 Repite la última consulta para comprobar el resultado. db.agg_alternative_1.find().sort({_id:1}) Puedes observar la diferencia que hay entre el uso de Map-Reduce y Aggregate. Caso 2: utiliza Map-Reduce y compara con Aggregate, añade además la cláusula finalize Escribe las siguientes funciones: var mapFunction2 = function() { for (var idx = 0; idx < this.items.length; idx++) { var key = this.items[idx].sku; var value = { count: 1, qty: this.items[idx].qty }; emit(key, value); } }; var reduceFunction2 = function(keySKU, countObjVals) { reducedVal = { count: 0, qty: 0 }; for (var idx = 0; idx < countObjVals.length; idx++) { reducedVal.count += countObjVals[idx].count; reducedVal.qty += countObjVals[idx].qty; } return reducedVal; }; © Universidad Internacional de La Rioja (UNIR) var finalizeFunction2 = function (key, reducedVal) { reducedVal.avg = reducedVal.qty/reducedVal.count; return reducedVal; }; Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 22 Ahora aplica las funciones sobre los documentos anteriores: db.norders.mapReduce( mapFunction2, reduceFunction2, { out: { merge: "map_reduce_example2" }, query: { ord_date: { $gte: new Date("2020-03-01") } }, finalize: finalizeFunction2 } ); Recuerda consultar la nueva colección producto del Map-Reduce creado previamente. db.map_reduce_example2.find().sort( { _id: 1 } ) Ahora realiza la misma operación anterior, pero utilizando la función aggregate. db.norders.aggregate( [ { $match: { ord_date: { $gte: new Date("2020-03-01") } } }, { $unwind: "$items" }, { $group: { _id: "$items.sku", qty: { $sum: "$items.qty" }, orders_ids: { $addToSet: "$_id" } } }, { $project: { value: { count: { $size: "$orders_ids" }, qty: "$qty", avg: { $divide: [ "$qty", { $size: "$orders_ids" } ] } } } }, { $merge: { into: "agg_alternative_3", on: "_id", whenMatched: "replace", whenNotMatched: "insert" } } © Universidad Internacional de La Rioja (UNIR) ] ) Repite la última consulta para comprobar el resultado. db.agg_alternative_3.find().sort( { _id: 1 } ) Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 23 Caso 3: utiliza Map-Reduce y compara con Aggregate, añade además la cláusula finalize y observa la agrupación incremental Para el siguiente ejercicio, utiliza el siguiente conjunto de documentos de la colección usersessions. 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 } ]) Escribe las siguientes funciones: var mapFunction = function() { var key = this.userid; var value = { total_time: this.length, count: 1, avg_time: 0 }; © Universidad Internacional de La Rioja (UNIR) emit( key, value ); }; var reduceFunction = function(key, values) { var reducedObject = { total_time: 0, count:0, avg_time:0 }; values.forEach(function(value) { reducedObject.total_time += value.total_time; Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 24 reducedObject.count += value.count; }); return reducedObject; }; var finalizeFunction = function(key, reducedValue) { if (reducedValue.count > 0) reducedValue.avg_time = reducedValue.total_time / reducedValue.count; return reducedValue; }; Ahora aplica las funciones sobre los documentos anteriores: db.usersessions.mapReduce( mapFunction, reduceFunction, { out: "session_stats", finalize: finalizeFunction } ) db.session_stats.find().sort( { _id: 1 } ) Observa el resultado obtenido. {"_id":"a","value":{"total_time":330, "count":3, "avg_time" : 110 } } {"_id":"b","value":{"total_time":270, "count":3, "avg_time" : 90 } } {"_id":"c","value":{"total_time":360, "count":3, "avg_time" : 120 } } © Universidad Internacional de La Rioja (UNIR) {"_id":"d","value":{"total_time":210, "count":3, "avg_time" : 70 } } Prueba ahora la siguiente forma y observa el resultado. db.usersessions.mapReduce( mapFunction, reduceFunction, Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 25 { query: { ts: { $gte: ISODate('2020-03-05 00:00:00') } }, out: { reduce: "session_stats" }, finalize: finalizeFunction } ) db.session_stats.find().sort( { _id: 1 } ) Realiza la misma tarea, pero ahora con aggregate. Utiliza el siguiente conjunto de documentos de la colección usersessions. 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", © Universidad Internacional de La Rioja (UNIR) 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" ] } ] } Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 26 } } ], whenNotMatched: "insert" }} ]) Ejecutar una consulta sobre la nueva colección. db.session_stats_agg.find().sort( { _id: 1 } ) Sugerencia: una vez finalizado el tema, publica un mensaje en el Foro de este tema dando tu punto de vista sobre las ventajas de usar Map-Reduce y Aggregate. Investiga un poco más sobre el tema y comenta si el hecho de que MongoDB use JavaScript dificulta de alguna manera el uso de Map-Reduce o Aggregate. Después de leer todo el tema, el reto siguiente es que hagas un repaso sobre el uso de Map-Reduce y lo compares con Aggregate. En los vídeos siguientes el profesor repasará los casos prácticos y comentará algunos aspectos que se deben tener en cuenta a la hora de trabajar con estos mecanismos. © Universidad Internacional de La Rioja (UNIR) Vídeo 1. Map-Reduce vs. Aggregate, caso práctico 1. Accede al vídeo a través del aula virtual Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 27 Vídeo 2. Map-Reduce vs. Aggregate, caso práctico 2. Accede al vídeo a través del aula virtual En esta otra clase, «Utilización del framework Aggregate», se explica cómo utilizar el framework Aggregate con ejemplos prácticos. Vídeo 3. Utilización del framework Aggregate. © Universidad Internacional de La Rioja (UNIR) Accede al vídeo a través del aula virtual Métodos de Captura y Almacenamiento de los Datos Tema 4. Ideas clave 28 A fondo MongoDB: the definitive guide Chodorow, K., y Dirolf, M. (2019). MongoDB: the definitive guide. O’Reilly. https://www.oreilly.com/library/view/mongodb-the-definitive/9781491954454/ Este libro contiene información detallada sobre la creación, eliminación y modificación de documentos en MongoDB. El capítulo 6 detalla las funciones de agregación. MongoDB Map-Reduce Sr. Fugu Data Science. (12 de mayo de 2020). Tutorial de MONGODB: REDUCCIÓN DE © Universidad Internacional de La Rioja (UNIR) MAPAS [Archivo de vídeo]. https://www.youtube.com/watch?v=MGZkKzfSqP4 Esta es una guía para principiantes de Map-Reduce (MongoDB) con ejemplos y casos de uso. También habrá ejemplos de agregación, para mostrar cuándo es posible que Map-Reduce no encaje. Métodos de Captura y Almacenamiento de los Datos Tema 4. A fondo 29 MongoDB Aggregation Framework Herrera, J. [Programar es fácil]. (8 de abril de 2020). Tutorial MongoDB 4.2 Parte 10 Agreaciones: Instrucción Aggregate $match $group $sum $avg $multiply [Archivo de vídeo]. https://www.youtube.com/watch?v=OV2byyfKHlw Esta es una guía de Aggregate en MongoDB con ejemplos y casos de uso. También habrá ejemplos de agregación, para mostrar cuándo es posible que Map-Reduce no encaje. Aggregation Framework MongoDB. (25 de junio de 2014). The Aggregation Framework [Archivo de vídeo]. © Universidad Internacional de La Rioja (UNIR) https://www.mongodb.com/presentations/aggregation-framework-0 Métodos de Captura y Almacenamiento de los Datos Tema 4. A fondo 30 La introducción a MongoDB presentada durante los primeros minutos de este vídeo incluye una breve descripción de las características del sistema. También presentan un ejemplo con las diferencias entre bases de datos relacionales y MongoDB. Documentación oficial de MongoDB MongoDB. (2021). Documentation [Página web]. http://docs.mongodb.org/ Dentro del sitio oficial con la documentación del sistema MongoDB, el contenido relevante para este tema es la sección MongoDB Map-Reduce y Aggregation Framework. Bibliografía Bradshaw, S., Brazil, E., y Chodorow, K. (2019). MongoDB: the definitive guide: powerful and scalable data storage. O'Reilly Media. 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. © Universidad Internacional de La Rioja (UNIR) Giamas, A. (2017). Mastering MongoDB 3.x: an expert's guide to building faulttolerant MongoDB applications. Packt Publishing. Tiwari, S. (2011). Professional NoSQL (pp. 97-135, 217-232). John Wiley & Sons. Métodos de Captura y Almacenamiento de los Datos Tema 4. A fondo 31 Test 1. ¿Para qué son útiles las funciones de agregación? A. Para agrupar datos. B. Para realizar cálculos. C. Para crear nuevas colecciones. D. Todas las anteriores son correctas. 2. ¿Qué técnica puede utilizarse en MongoDB para agregar información de documentos en una collection? A. sum. B. Aggregate, a partir de la versión 2.2. C. Map-Reduce. D. Las respuestas B y C son correctas. 3. ¿Cuál de las siguientes son operaciones específicas de agregación? A. distinct. B. Map-Reduce. C. count. D. Las respuestas A y C son correctas. 4. ¿Cuál es el objetivo principal de la función map? A. Generar los pares clave-valor. B. Realizar operaciones con los atributos de la colección. © Universidad Internacional de La Rioja (UNIR) C. Operar sobre los pares clave-valor. D. Crear una nueva colección. Métodos de Captura y Almacenamiento de los Datos Tema 4. Test 32 5. ¿Cuál es el objetivo principal de la función reduce? A. Generar los pares clave-valor. B. Realizar operaciones con los atributos de la colección. C. Operar sobre los pares clave-valor. D. Crear una nueva colección. 6. ¿Qué función se utiliza en la fase de Map para generar el par clave-valor que será procesado posteriormente? A. generate. B. return. C. emit. D. yield. 7. ¿Cuál de las siguientes es una ventaja de framework de agregación de MongoDB? A. Rendimiento. B. Potencia. C. Simplicidad. D. Las respuestas A y C son correctas. 8. ¿En qué está modelado el framework de agregación? A. Funciones. B. Etapas. C. Sentencias SQL. D. Agrupaciones. © Universidad Internacional de La Rioja (UNIR) 9. ¿Qué campo es obligatorio especificar en framework de agregación? A. _id. B. Object. C. $sum. D. $group. Métodos de Captura y Almacenamiento de los Datos Tema 4. Test 33 10. ¿Cuál de los siguientes es un operador del framework de agregación? A. $gt. B. $map. C. $year. © Universidad Internacional de La Rioja (UNIR) D. Todos los anteriores son correctos. Métodos de Captura y Almacenamiento de los Datos Tema 4. Test 34