Nota
Canalización de agregación como alternativa a Map-Reduce
A partir de MongoDB 5.0, map-reduce está obsoleto:
En lugar de map-reduce, debería usar una canalización de agregación. Las canalizaciones de agregación ofrecen mejor rendimiento y usabilidad que map-reduce.
Puede reescribir las operaciones de map-reduce utilizando etapas de canalización de agregación, como
$group, y$mergeotros.Para las operaciones map-reduce que requieren una funcionalidad personalizada, puedes utilizar los operadores de agregación
$accumulatory$function. Puedes utilizar esos operadores para definir expresiones de agregación personalizadas en JavaScript.
Para ejemplos de alternativas de pipeline de agregación a map-reduce, consulte:
Importante
Método mongosh
Esta página documenta una mongosh Método. Esta no es la documentación para comandos de base de datos ni para controladores específicos del lenguaje, como Node.js.
Para el comando de base de datos, consulta el comando mapReduce.
Para los drivers de API de MongoDB, consulte la documentación del driver de MongoDB específica del lenguaje.
Definición
db.collection.mapReduce(map,reduce, { <options> })Nota
Las vistas no dan soporte a operaciones de map-reduce.
Compatibilidad
Este método está disponible en implementaciones alojadas en los siguientes entornos:
MongoDB Atlas: El servicio totalmente gestionado para implementaciones de MongoDB en la nube
Importante
Este comando no es compatible con los clústeres M0 y Flex. Para obtener más información, consulta Comandos no compatibles.
MongoDB Enterprise: La versión basada en suscripción y autogestionada de MongoDB
MongoDB Community: La versión de MongoDB con código fuente disponible, de uso gratuito y autogestionada.
Sintaxis
Nota
MongoDB ignora la opción verbose.
A partir de la versión 4.2, MongoDB deja obsoleto:
La opción map-reduce para crear una nueva colección fragmentada, así como el uso de la opción sharded para map-reduce. Para generar una colección fragmentada, primero créela. MongoDB 4.2 también desaprueba el reemplazo de una colección fragmentada existente.
db.collection.mapReduce() tiene la siguiente sintaxis:
db.collection.mapReduce( <map>, <reduce>, { out: <collection>, query: <document>, sort: <document>, limit: <number>, finalize: <function>, scope: <document>, jsMode: <boolean>, verbose: <boolean>, bypassDocumentValidation: <boolean> } )
Parámetros
db.collection.mapReduce() toma los siguientes parámetros:
Parameter | Tipo | Descripción |
|---|---|---|
| JavaScript o cadena | Una función de JavaScript que asocia o "mapea" un Consulte Requisitos para la función de mapa para obtener más información. |
| JavaScript o cadena | Una función de JavaScript que reduce a un solo objeto todos los Consulte Requisitos para la función de reducción para obtener más información. |
| Documento | Un documento que especifica parámetros adicionales |
Campos
La siguiente tabla describe argumentos adicionales que puede db.collection.mapReduce() aceptar.
Campo | Tipo | Descripción | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| string o documento | Especifica la ubicación del resultado de la operación map-reduce. Puede generar la Consulte nuestras Opciones para obtener más información. | ||||||||||
| Documento | Especifica los criterios de selección utilizando operadores de consulta para determinar los documentos de entrada a la | ||||||||||
| Documento | Ordena los documentos de entrada. Esta opción es útil para la optimización. Por ejemplo, especifica que la clave de ordenación sea la misma que la clave de emisión para que haya menos operaciones de reducción. La clave de ordenamiento debe estar en un índice existente para esta colección. | ||||||||||
| Número | Especifica un número máximo de documentos para la entrada en la función | ||||||||||
| Javascript o cadena | Opcional. Una función de JavaScript que modifica la salida después de la función Consulte Requisitos para la función finalizar para obtener más información. | ||||||||||
| Documento | Especifica variables globales a las que se puede acceder en las funciones | ||||||||||
| booleano | Especifica si se deben convertir los datos intermedios al formato BSON entre la ejecución de las funciones Se establece por defecto en Si
Si
| ||||||||||
| booleano | Especifica si se debe incluir la información Se establece por defecto en Esta opción se ignora. La información del resultado siempre excluye la | ||||||||||
| Documento | Opcional. Especifica la intercalación a utilizar para la operación. La intercalación permite a los usuarios especificar reglas propias del lenguaje para la comparación de strings, como reglas para el uso de mayúsculas y minúsculas y marcas de acento. La opción de intercalación tiene la siguiente sintaxis: Al especificar la intercalación, el campo Si no se especifica la intercalación, pero la colección tiene una intercalación por defecto (ver Si no se especifica ninguna intercalación para la colección o para las operaciones, MongoDB utiliza la comparación binaria simple usada en versiones anteriores para las comparaciones de strings. No puedes especificar varias intercalaciones para una operación. Por ejemplo, no puedes especificar diferentes intercalaciones por campo, o si realizas una búsqueda con un ordenamiento, no puedes usar una intercalación para la búsqueda y otra para el ordenamiento. | ||||||||||
| booleano | Opcional. Permite que |
Nota
map-reduce operations Las $where expresiones de operador y no pueden acceder a ciertas funciones o propiedades globales,db como, que están disponibles en.mongosh
Las siguientes funciones y propiedades de JavaScript están disponibles para map-reduce operations y $where expresiones de operador:
Propiedades disponibles | Funciones disponibles | |
|---|---|---|
argsMaxKeyMinKey | assert()BinData()DBPointer()DBRef()doassert()emit()gc()HexData()hex_md5()isNumber()isObject()ISODate()isString() | Map()MD5()NumberInt()NumberLong()ObjectId()print()printjson()printjsononeline()sleep()Timestamp()tojson()tojsononeline()tojsonObject()UUID()version() |
Requisitos para la map función
La función map se encarga de transformar cada documento de entrada en cero o más documentos. Puede acceder a las variables definidas en el parámetro scope y tiene el siguiente prototipo:
function() { ... emit(key, value); }
La función map tiene los siguientes requisitos:
En la función
map, hace referencia al documento actual comothisdentro de la función.La
mapfunción no debe acceder a la base de datos por ningún motivo.La función
mapdebe ser pura, o no tener ningún impacto fuera de la función (es decir, efectos secundarios.)La función
mappuede llamar opcionalmente aemit(key,value)cualquier cantidad de veces para crear un documento de salida que asociekeyconvalue.
La siguiente función map llamará a emit(key,value) 0 o 1 veces dependiendo del valor del campo status del documento de entrada:
function() { if (this.status == 'A') emit(this.cust_id, 1); }
La siguiente función map puede llamar a emit(key,value) varias veces dependiendo de la cantidad de elementos en el campo items del documento de entrada:
function() { this.items.forEach(function(item){ emit(item.sku, 1); }); }
Requisitos para la reduce función
La función reduce tiene el siguiente prototipo:
function(key, values) { ... return result; }
La función reduce exhibe los siguientes comportamientos:
La
reducefunción no debe acceder a la base de datos, ni siquiera para realizar operaciones de lectura.La
reducefunción no debería afectar al sistema externo.MongoDB puede invocar la función
reducemás de una vez para la misma clave. En este caso, la salida anterior de la funciónreducepara esa clave se convertirá en uno de los valores de entrada para la siguiente invocación de la funciónreducepara esa clave.La función
reducepuede acceder a las variables definidas en el parámetroscope.Las entradas para
reduceno deben ser mayores a la mitad del tamaño máximo de documento BSON de MongoDB. Este requisito podría no cumplirse cuando se devuelven documentos grandes y luego se combinan en pasos posteriores dereduce.
Dado que es posible invocar la función reduce más de una vez para la misma clave, las siguientes propiedades deben ser verdaderas:
El tipo del objeto de retorno debe ser idéntico al tipo del
valueemitido por lamapfunción.la función
reducedebe ser asociativa. La siguiente instrucción debe ser verdadera:reduce(key, [ C, reduce(key, [ A, B ]) ] ) == reduce( key, [ C, A, B ] ) La
reducefunción debe ser idempotente. Asegúrese de que la siguiente afirmación sea verdadera:reduce( key, [ reduce(key, valuesArray) ] ) == reduce( key, valuesArray ) La
reducefunción debe ser conmutativa: es decir, el orden de los elementos envaluesArrayno debe afectar la salida de lareducefunción, de modo que la siguiente afirmación sea verdadera:reduce( key, [ A, B ] ) == reduce( key, [ B, A ] )
out opciones
Puede especificar las siguientes opciones para el parámetro out:
Salida a una colección
Esta opción genera la salida en una nueva colección y no está disponible en los miembros secundarios de sets de réplicas.
out: <collectionName>
Salida a una colección con una acción
Nota
A partir de la versión 4.2, MongoDB deja obsoleto:
La opción map-reduce para crear una nueva colección fragmentada, así como el uso de la opción sharded para map-reduce. Para generar una colección fragmentada, primero créela. MongoDB 4.2 también desaprueba el reemplazo de una colección fragmentada existente.
Esta opción solo está disponible al transferir una colección ya existente a out. No está disponible en miembros secundarios de conjuntos de réplicas.
out: { <action>: <collectionName> [, db: <dbName>] [, sharded: <boolean> ] }
Cuando se envía a una colección con una acción, out tiene los siguientes parámetros:
<action>:Especifique una de las siguientes acciones:replaceReemplace el contenido de la
<collectionName>si la colección con la<collectionName>existe.mergeCombina el nuevo resultado con el resultado existente si la colección de salida ya existe. Si un documento existente tiene la misma clave que el nuevo resultado, sobrescribe ese documento existente.
reduceFusionar el nuevo resultado con el existente si la colección de salida ya existe. Si un documento existente tiene la misma clave que el nuevo resultado, aplicar la función
reducetanto al documento nuevo como al existente y sobrescribir el documento existente con el resultado.
db:Opcional. El nombre de la base de datos donde desea que la operación map-reduce escriba su salida. Por defecto, será la misma base de datos que la colección de entrada.
Salida en línea
Ejecuta la operación map-reduce en memoria y devuelve el resultado. Esta opción es la única disponible para out en miembros secundarios de conjuntos de réplicas.
out: { inline: 1 }
El resultado debe ajustarse al tamaño máximo de un documento BSON.
Requisitos para la finalize función
La función finalize tiene el siguiente prototipo:
function(key, reducedValue) { ... return modifiedObject; }
La función finalize recibe como argumentos un valor key y el valor reducedValue de la función reduce. Tenga en cuenta que:
La
finalizefunción no debe acceder a la base de datos por ningún motivo.La función
finalizedebe ser pura, o no tener ningún impacto fuera de la función (es decir, efectos secundarios.)La función
finalizepuede acceder a las variables definidas en el parámetroscope.
Ejemplos de Map-Reduce
Los ejemplos de esta sección incluyen alternativas de canalización de agregación sin expresiones de agregación personalizadas. Para alternativas que utilizan expresiones personalizadas, consulte Ejemplos de traducción de Map-Reduce a canalización de agregación.
Crea una colección de muestra orders con estos documentos:
db.orders.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" }, { _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" } ])
Devolver el precio total por cliente
Realice la operación map-reduce en la colección orders para agrupar por cust_id y calcular la suma de price para cada cust_id:
Define la función de mapa para procesar cada documento de entrada:
En la función,
thishace referencia al documento que la operación map-reduce está procesando.La función asigna
priceacust_idpara cada documento y emitecust_idyprice.
var mapFunction1 = function() { emit(this.cust_id, this.price); }; Define la función de reducción correspondiente con dos argumentos
keyCustIdyvaluesPrices:valuesPriceses una matriz cuyos elementos son los valorespriceemitidos por la función de mapa y agrupados porkeyCustId.La función reduce la matriz
valuesPricea la suma de sus elementos.
var reduceFunction1 = function(keyCustId, valuesPrices) { return Array.sum(valuesPrices); }; Realice map-reduce en todos los documentos de la colección
ordersutilizando la función mapmapFunction1y la función reducereduceFunction1:db.orders.mapReduce( mapFunction1, reduceFunction1, { out: "map_reduce_example" } ) Esta operación envía los resultados a una colección llamada
map_reduce_example. Si la colecciónmap_reduce_exampleya existe, la operación reemplazará el contenido con los resultados de esta operación de map-reduce.Consulta la colección
map_reduce_examplepara verificar los resultados:db.map_reduce_example.find().sort( { _id: 1 } ) La operación devuelve estos documentos:
{ "_id" : "Ant O. Knee", "value" : 95 } { "_id" : "Busby Bee", "value" : 125 } { "_id" : "Cam Elot", "value" : 60 } { "_id" : "Don Quis", "value" : 155 }
Alternativa de agregación
Al utilizar los operadores de canalización de agregación disponibles, puede reescribir la operación map-reduce sin definir funciones personalizadas:
db.orders.aggregate([ { $group: { _id: "$cust_id", value: { $sum: "$price" } } }, { $out: "agg_alternative_1" } ])
La
$groupetapacust_idagrupa por y calcula elvaluecampo (véase también).$sumElvaluecampo contiene el totalpricede paracust_idcada.La etapa envía los siguientes documentos a la siguiente etapa:
{ "_id" : "Don Quis", "value" : 155 } { "_id" : "Ant O. Knee", "value" : 95 } { "_id" : "Cam Elot", "value" : 60 } { "_id" : "Busby Bee", "value" : 125 } Luego, escribe la salida en
$outlaagg_alternative_1colección. Como alternativa, podría usar en$mergelugar$outde.Consulta la colección
agg_alternative_1para verificar los resultados:db.agg_alternative_1.find().sort( { _id: 1 } ) La operación devuelve los siguientes documentos:
{ "_id" : "Ant O. Knee", "value" : 95 } { "_id" : "Busby Bee", "value" : 125 } { "_id" : "Cam Elot", "value" : 60 } { "_id" : "Don Quis", "value" : 155 }
Tip
Para obtener una alternativa que utilice expresiones de agregación personalizadas, consulte Ejemplos de traducción de Map-Reduce a canalización de agregación.
Calcular el pedido y la cantidad total con la cantidad promedio por artículo
En el siguiente ejemplo, verá una operación de mapa-reducción en la colección orders para todos los documentos que tengan un valor ord_date mayor o igual a 2020-03-01.
La operación en el ejemplo:
Agrupa por el campo
item.skuy calcula la cantidad de pedidos y la cantidad total solicitada para cadasku.Calcula la cantidad promedio por pedido para cada valor
skuy fusiona los resultados en la colección de salida.
Al fusionar resultados, si un documento existente tiene la misma clave que el nuevo resultado, la operación lo sobrescribe. Si no existe ningún documento con la misma clave, la operación lo inserta.
Pasos de ejemplo:
Define la función de mapa para procesar cada documento de entrada:
En la función,
thishace referencia al documento que la operación map-reduce está procesando.Para cada artículo, la función asocia el
skucon un nuevo objetovalueque contiene elcountde1y el artículoqtypara el pedido y emite elsku(almacenado en elkey) y elvalue.
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); } }; Define la función de reducción correspondiente con dos argumentos
keySKUycountObjVals:countObjValses una matriz cuyos elementos son los objetos asignados a los valores agrupadoskeySKUpasados por la función de mapa a la función reductora.La función reduce la matriz
countObjValsa un solo objetoreducedValueque contiene los camposcountyqty.En
reducedVal, el campocountcontiene la suma de loscountcampos de los elementos individuales de la matriz, y el campoqtycontiene la suma de losqtycampos de los elementos individuales de la matriz.
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; }; Define una función de finalización con dos argumentos
keyyreducedVal. La función modifica el objetoreducedValpara añadir un campo calculado llamadoavgy devuelve el objeto modificado:var finalizeFunction2 = function (key, reducedVal) { reducedVal.avg = reducedVal.qty/reducedVal.count; return reducedVal; }; Realice la operación map-reduce en la colección
ordersutilizando las funcionesmapFunction2,reduceFunction2yfinalizeFunction2:db.orders.mapReduce( mapFunction2, reduceFunction2, { out: { merge: "map_reduce_example2" }, query: { ord_date: { $gte: new Date("2020-03-01") } }, finalize: finalizeFunction2 } ); Esta operación utiliza el campo
querypara seleccionar solo los documentos con un valorord_datemayor o igual anew Date("2020-03-01"). Luego, envía los resultados a una colecciónmap_reduce_example2.Si la colección
map_reduce_example2ya existe, la operación fusionará el contenido existente con los resultados de esta operación de map-reduce. Es decir, si un documento existente tiene la misma clave que el nuevo resultado, la operación lo sobrescribe. Si no existe ningún documento con la misma clave, la operación lo inserta.Consulta la colección
map_reduce_example2para verificar los resultados:db.map_reduce_example2.find().sort( { _id: 1 } ) La operación devuelve estos documentos:
{ "_id" : "apples", "value" : { "count" : 4, "qty" : 35, "avg" : 8.75 } } { "_id" : "carrots", "value" : { "count" : 2, "qty" : 15, "avg" : 7.5 } } { "_id" : "chocolates", "value" : { "count" : 3, "qty" : 15, "avg" : 5 } } { "_id" : "oranges", "value" : { "count" : 7, "qty" : 63, "avg" : 9 } } { "_id" : "pears", "value" : { "count" : 1, "qty" : 10, "avg" : 10 } }
Alternativa de agregación
Al utilizar los operadores de canalización de agregación disponibles, puede reescribir la operación map-reduce sin definir funciones personalizadas:
db.orders.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" } } ] )
La etapa selecciona solo aquellos documentos
$matchconord_datemayor o igualnew Date("2020-03-01")a.La etapa desglosa el documento por
$unwindelitemscampo de la matriz para generar un documento por cada elemento de la matriz. Por ejemplo:{ "_id" : 1, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-01T00:00:00Z"), "price" : 25, "items" : { "sku" : "oranges", "qty" : 5, "price" : 2.5 }, "status" : "A" } { "_id" : 1, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-01T00:00:00Z"), "price" : 25, "items" : { "sku" : "apples", "qty" : 5, "price" : 2.5 }, "status" : "A" } { "_id" : 2, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 70, "items" : { "sku" : "oranges", "qty" : 8, "price" : 2.5 }, "status" : "A" } { "_id" : 2, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 70, "items" : { "sku" : "chocolates", "qty" : 5, "price" : 10 }, "status" : "A" } { "_id" : 3, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 50, "items" : { "sku" : "oranges", "qty" : 10, "price" : 2.5 }, "status" : "A" } { "_id" : 3, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 50, "items" : { "sku" : "pears", "qty" : 10, "price" : 2.5 }, "status" : "A" } { "_id" : 4, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-18T00:00:00Z"), "price" : 25, "items" : { "sku" : "oranges", "qty" : 10, "price" : 2.5 }, "status" : "A" } { "_id" : 5, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-19T00:00:00Z"), "price" : 50, "items" : { "sku" : "chocolates", "qty" : 5, "price" : 10 }, "status" : "A" } ... La etapa
$groupitems.skuse agrupa por, calculando para cada SKU:- El campo
qty. El campoqtycontiene el - total
qtypedidos por cadaitems.sku$sum(Ver).
- El campo
- La matriz
orders_ids. El campoorders_idscontiene un - matriz de órdenes distintos
_idpara elitems.sku$addToSet(ver).
- La matriz
{ "_id" : "chocolates", "qty" : 15, "orders_ids" : [ 2, 5, 8 ] } { "_id" : "oranges", "qty" : 63, "orders_ids" : [ 4, 7, 3, 2, 9, 1, 10 ] } { "_id" : "carrots", "qty" : 15, "orders_ids" : [ 6, 9 ] } { "_id" : "apples", "qty" : 35, "orders_ids" : [ 9, 8, 1, 6 ] } { "_id" : "pears", "qty" : 10, "orders_ids" : [ 3 ] } La etapa modifica el documento de salida para reflejar la salida de map-reduce y tener dos
$projectcampos:_idvaluey. La$projectetapa establece:La etapa desglosa el documento por
$unwindelitemscampo de la matriz para generar un documento por cada elemento de la matriz. Por ejemplo:{ "_id" : 1, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-01T00:00:00Z"), "price" : 25, "items" : { "sku" : "oranges", "qty" : 5, "price" : 2.5 }, "status" : "A" } { "_id" : 1, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-01T00:00:00Z"), "price" : 25, "items" : { "sku" : "apples", "qty" : 5, "price" : 2.5 }, "status" : "A" } { "_id" : 2, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 70, "items" : { "sku" : "oranges", "qty" : 8, "price" : 2.5 }, "status" : "A" } { "_id" : 2, "cust_id" : "Ant O. Knee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 70, "items" : { "sku" : "chocolates", "qty" : 5, "price" : 10 }, "status" : "A" } { "_id" : 3, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 50, "items" : { "sku" : "oranges", "qty" : 10, "price" : 2.5 }, "status" : "A" } { "_id" : 3, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-08T00:00:00Z"), "price" : 50, "items" : { "sku" : "pears", "qty" : 10, "price" : 2.5 }, "status" : "A" } { "_id" : 4, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-18T00:00:00Z"), "price" : 25, "items" : { "sku" : "oranges", "qty" : 10, "price" : 2.5 }, "status" : "A" } { "_id" : 5, "cust_id" : "Busby Bee", "ord_date" : ISODate("2020-03-19T00:00:00Z"), "price" : 50, "items" : { "sku" : "chocolates", "qty" : 5, "price" : 10 }, "status" : "A" } ... La etapa
$groupitems.skuse agrupa por, calculando para cada SKU:El
qtycampo. Elqtycampo contiene el total deqtypedidos por cadaitems.sku$sumutilizando.La
orders_idsmatriz. Elorders_idscampo contiene una matriz_iditems.sku$addToSetde de orden distintopara el que utiliza.
{ "_id" : "chocolates", "qty" : 15, "orders_ids" : [ 2, 5, 8 ] } { "_id" : "oranges", "qty" : 63, "orders_ids" : [ 4, 7, 3, 2, 9, 1, 10 ] } { "_id" : "carrots", "qty" : 15, "orders_ids" : [ 6, 9 ] } { "_id" : "apples", "qty" : 35, "orders_ids" : [ 9, 8, 1, 6 ] } { "_id" : "pears", "qty" : 10, "orders_ids" : [ 3 ] } La etapa modifica el documento de salida para reflejar la salida de map-reduce y tener dos
$projectcampos:_idvaluey. La$projectetapa establece:el
value.countal tamaño de laorders_idsmatriz$sizeutilizando.el campo
value.qtyalqtydel documento de entrada.el
value.avgal número promedio de cantidades por pedido utilizando$divide$sizey.
{ "_id" : "apples", "value" : { "count" : 4, "qty" : 35, "avg" : 8.75 } } { "_id" : "pears", "value" : { "count" : 1, "qty" : 10, "avg" : 10 } } { "_id" : "chocolates", "value" : { "count" : 3, "qty" : 15, "avg" : 5 } } { "_id" : "oranges", "value" : { "count" : 7, "qty" : 63, "avg" : 9 } } { "_id" : "carrots", "value" : { "count" : 2, "qty" : 15, "avg" : 7.5 } } Finalmente, escribe la salida en
$mergelaagg_alternative_3colección. Si un documento existente tiene la misma clave_idque el nuevo resultado, la operación sobrescribe el documento existente. Si no existe ningún documento con la misma clave, la operación inserta el documento.Consulta la colección
agg_alternative_3para verificar los resultados:db.agg_alternative_3.find().sort( { _id: 1 } ) La operación devuelve los siguientes documentos:
{ "_id" : "apples", "value" : { "count" : 4, "qty" : 35, "avg" : 8.75 } } { "_id" : "carrots", "value" : { "count" : 2, "qty" : 15, "avg" : 7.5 } } { "_id" : "chocolates", "value" : { "count" : 3, "qty" : 15, "avg" : 5 } } { "_id" : "oranges", "value" : { "count" : 7, "qty" : 63, "avg" : 9 } } { "_id" : "pears", "value" : { "count" : 1, "qty" : 10, "avg" : 10 } }
Tip
Para obtener una alternativa que utilice expresiones de agregación personalizadas, consulte Ejemplos de traducción de Map-Reduce a canalización de agregación.
Salida
La salida del métododb.collection.mapReduce()es idéntica a la del comandomapReduce. Consulte la sección "Salida" del comandomapReducepara obtener información sobre la salidadb.collection.mapReduce().
Restricciones
db.collection.mapReduce()ya no admite afterClusterTime. Por lo tanto, db.collection.mapReduce()no puede asociarse con sesiones causalmente consistentes.