Docs Menu
Docs Home
/ /

mapReduce (comando de base de datos)

Nota

Canalización de agregación como alternativa a Map-Reduce

A partir de MongoDB 5.0, map-reduce está obsoleto:

Para ejemplos de alternativas de pipeline de agregación a map-reduce, consulte:

mapReduce

El mapReduce El comando le permite ejecutar operaciones de agregación de mapas y reducciones en una colección.

Tip

mongoshEn, este comando también se puede ejecutar a través del método mapReduce() auxiliar.

Los métodos asistente son convenientes para usuarios de mongosh, pero es posible que no proporcionen el mismo nivel de información que los comandos de base de datos. En los casos en que no se necesite la conveniencia o se requieran campos de retorno adicionales, utiliza el comando de base de datos.

Este comando 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.

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, créela primero. MongoDB 4.2 también desaprueba el reemplazo de una colección fragmentada existente.

El comando tiene la siguiente sintaxis:

db.runCommand(
{
mapReduce: <string>,
map: <string or JavaScript>,
reduce: <string or JavaScript>,
finalize: <string or JavaScript>,
out: <output>,
query: <document>,
sort: <document>,
limit: <number>,
scope: <document>,
jsMode: <boolean>,
verbose: <boolean>,
bypassDocumentValidation: <boolean>,
collation: <document>,
maxTimeMS: <integer>,
writeConcern: <document>,
comment: <any>
}
)

El comando toma los siguientes campos como argumentos:

Campo
Tipo
Descripción

string

El nombre de la colección en la que se desea realizar la función map-reduce. Esta colección se filtrará con query antes de ser procesada por la función map.

Las vistas no dan soporte a operaciones de map-reduce.

JavaScript o cadena

Una función de JavaScript que asocia o "mapea" un value con un key y emite el key y el valor pair. Puedes especificar la función como tipo BSON Javascript (BSON Type 13) o String (BSON Type 2).

Para obtener más información, consulte Requisitos para la función de mapa.

JavaScript o cadena

Una función de JavaScript que reduce a un solo objeto todos los values asociados a un key específico. Puede especificar la función como JavaScript de tipo BSON (tipo BSON 13) o cadena (tipo BSON 2).

Para obtener más información, consulte Requisitos para la función de reducción.

string o documento

Especifica dónde se mostrará el resultado de la operación map-reduce. Puede mostrarlo en una colección o devolverlo en línea. En un miembro principal de un conjunto de réplicas, puede mostrarlo en una colección o en línea, pero en un miembro secundario, solo es posible la salida en línea.

Para obtener más información,consulte nuestras Opciones.

Documento

Opcional. Especifica los criterios de selección mediante operadores de consulta para determinar los documentos de entrada a la map función.

Documento

Opcional. Ordena los documentos de entrada. Esta opción es útil para la optimización. Por ejemplo, especifique que la clave de ordenación sea la misma que la clave de emisión para reducir las operaciones de reducción. La clave de ordenación debe estar en un índice existente para esta colección.

Número

Opcional. Especifica un número máximo de documentos para la entrada a la función map.

JavaScript o cadena

Opcional. Una función de JavaScript que modifica la salida después de la función reduce. Puede especificar la función como JavaScript de tipo BSON (tipo BSON 13) o cadena (tipo BSON 2).

Para obtener más información, consulte Requisitos para la función finalizar.

Documento

Opcional. Especifica las variables globales a las que se puede acceder en las funciones map, reduce y finalize.

booleano

Opcional. Especifica si se debe convertir los datos intermedios al formato BSON entre la ejecución de las funciones map y reduce.

Se establece por defecto en false.

Si false:

  • Internamente, MongoDB convierte los objetos JavaScript emitidos por la función map en objetos BSON. Estos objetos BSON se convierten de nuevo en objetos JavaScript al llamar a la función reduce.

  • La operación de map-reduce coloca los objetos intermedios BSON en un almacenamiento temporal en disco. Esto permite que la operación map-reduce se ejecute con conjuntos de datos arbitrariamente grandes.

Si true:

  • Internamente, los objetos JavaScript emitidos durante la función map permanecen como objetos JavaScript. No es necesario convertirlos para la función reduce, lo que puede resultar en una ejecución más rápida.

  • Solo puede utilizar jsMode para conjuntos de resultados con menos de 500,000 argumentos key distintos para la función emit() del asignador.

booleano

Opcional. Especifica si se debe incluir la información timing en la información del resultado. Configure de verbose a true para incluir la información timing.

Se establece por defecto en false.

Esta opción se ignora. La información del resultado siempre excluye la timing información. Puede ver la información de tiempo ejecutando explain con el comando en mapReduce los "executionStats" "allPlansExecution" verbosity modos, y.

booleano

Opcional. Permite que mapReduce omita la validación de esquema durante la operación. Esto permite insertar documentos que no cumplen con los requisitos de validación.

Si la opción de salida se establece inline en, no se realiza ninguna validación del esquema. Si la salida se dirige a una colección, cumple las reglas de validación de la colección y no inserta ningún documento no válido a menos quemapReduce el bypassDocumentValidation parámetro se establezca en verdadero.

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:

collation: {
locale: <string>,
caseLevel: <boolean>,
caseFirst: <string>,
strength: <int>,
numericOrdering: <boolean>,
alternate: <string>,
maxVariable: <string>,
backwards: <boolean>
}

Al especificar la intercalación, el campo locale es obligatorio; todos los demás campos de intercalación son opcionales. Para las descripciones de los campos, consulta Documento de intercalación.

Si no se especifica la intercalación, pero la colección tiene una intercalación por defecto (ver db.createCollection()), la operación utiliza la intercalación especificada para la colección.

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.

maxTimeMS

non-negative integer

Opcional.

Especifica un límite de tiempo en milisegundos. Si no especifica un valor para maxTimeMS, las operaciones no agotarán el tiempo de espera. Un valor de 0 especifica explícitamente el comportamiento por defecto sin límites.

MongoDB finaliza las operaciones que exceden su límite de tiempo asignado utilizando el mismo mecanismo que db.killOp(). MongoDB solo termina una operación en uno de sus puntos de interrupción designados.

Documento

Opcional. Un documento que expresa la preocupación de escritura que se usará al enviar datos a una colección. Omitir la preocupación de escritura predeterminada.

comment

any

Opcional. Un comentario proporcionado por el usuario para adjuntar a este comando. Una vez configurado, este comentario aparece junto a los registros de este comando en las siguientes ubicaciones:

Un comentario puede ser de cualquier tipo BSON válido (string, objeto, arreglo, etc.).

El siguiente es un uso prototipo del mapReduce comando:

var mapFunction = function() { ... };
var reduceFunction = function(key, values) { ... };
db.runCommand(
{
mapReduce: <input-collection>,
map: mapFunction,
reduce: reduceFunction,
out: { merge: <output-collection> },
query: <query>
}
)

Nota

JavaScript en MongoDB

Aunque usa JavaScript, la mayoría de las interacciones mapReduce con MongoDB no usan JavaScript sino que usan un controlador idiomático en el lenguaje de la aplicación que interactúa.

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 como this dentro de la función.

  • La map función no debe acceder a la base de datos por ningún motivo.

  • La función map debe ser pura, o no tener ningún impacto fuera de la función (es decir, efectos secundarios.)

  • La función map puede llamar opcionalmente a emit(key,value) cualquier cantidad de veces para crear un documento de salida que asocie key con value.

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); });
}

La función reduce tiene el siguiente prototipo:

function(key, values) {
...
return result;
}

La función reduce exhibe los siguientes comportamientos:

  • La reduce función no debe acceder a la base de datos, ni siquiera para realizar operaciones de lectura.

  • La reduce función no debería afectar al sistema externo.

  • MongoDB puede invocar la función reduce más de una vez para la misma clave. En este caso, la salida anterior de la función reduce para esa clave se convertirá en uno de los valores de entrada para la siguiente invocación de la función reduce para esa clave.

  • La función reduce puede acceder a las variables definidas en el parámetro scope.

  • Las entradas para reduce no 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 de reduce.

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 value emitido por la map función.

  • la función reduce debe ser asociativa. La siguiente instrucción debe ser verdadera:

    reduce(key, [ C, reduce(key, [ A, B ]) ] ) == reduce( key, [ C, A, B ] )
  • La reduce función debe ser idempotente. Asegúrese de que la siguiente afirmación sea verdadera:

    reduce( key, [ reduce(key, valuesArray) ] ) == reduce( key, valuesArray )
  • La reduce función debe ser conmutativa: es decir, el orden de los elementos en valuesArray no debe afectar la salida de la reduce función, de modo que la siguiente afirmación sea verdadera:

    reduce( key, [ A, B ] ) == reduce( key, [ B, A ] )

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 finalize función no debe acceder a la base de datos por ningún motivo.

  • La función finalize debe ser pura, o no tener ningún impacto fuera de la función (es decir, efectos secundarios.)

  • La función finalize puede acceder a las variables definidas en el parámetro scope.

Puede especificar las siguientes opciones para el parámetro out:

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>

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, créela primero. 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:

    • replace

      Reemplace el contenido de la <collectionName> si la colección con la <collectionName> existe.

    • merge

      Combina 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.

    • reduce

      Fusionar 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 reduce tanto 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.

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.

Si su implementación de MongoDB exige autenticación, el usuario que ejecuta el comando debe poseer las siguientes acciones de mapReduce privilegio:

Map-reduce con la opción de salida {out : inline}:

Map-reduce con la replace acción al enviar a una colección:

Map-reduce con las merge reduce acciones o al enviar a una colección:

La readWrite función integrada proporciona los permisos necesarios para realizar la agregación de mapas y reducciones.

El comando mapReduce ya no admite afterClusterTime. Por lo tanto, no se puede asociarmapReduce con sesiones causalmente consistentes.

Enmongosh, el métododb.collection.mapReduce()envuelve el comandomapReduce. Los siguientes ejemplos utilizan el métododb.collection.mapReduce():

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" }
])

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:

  1. Define la función de mapa para procesar cada documento de entrada:

    • En la función, this hace referencia al documento que la operación map-reduce está procesando.

    • La función asigna price a cust_id para cada documento y emite cust_id y price.

    var mapFunction1 = function() {
    emit(this.cust_id, this.price);
    };
  2. Define la función de reducción correspondiente con dos argumentos keyCustId y valuesPrices:

    • valuesPrices es una matriz cuyos elementos son los valores price emitidos por la función de mapa y agrupados por keyCustId.

    • La función reduce la matriz valuesPrice a la suma de sus elementos.

    var reduceFunction1 = function(keyCustId, valuesPrices) {
    return Array.sum(valuesPrices);
    };
  3. Realice map-reduce en todos los documentos de la colección orders utilizando la función map mapFunction1 y la función reduce reduceFunction1:

    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ón map_reduce_example ya existe, la operación reemplazará el contenido con los resultados de esta operación de map-reduce.

  4. Consulta la colección map_reduce_example para 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 }

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" }
])
  1. La $group etapa cust_id agrupa por y calcula el value campo (véase también).$sum El value campo contiene el total price de para cust_id cada.

    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 }
  2. Luego, escribe la salida en $out la agg_alternative_1 colección. Como alternativa, podría usar en $merge lugar $out de.

  3. Consulta la colección agg_alternative_1 para 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.

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:

  1. Agrupa por el campo item.sku y calcula la cantidad de pedidos y la cantidad total solicitada para cada sku.

  2. Calcula la cantidad promedio por pedido para cada valor sku y 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:

  1. Define la función de mapa para procesar cada documento de entrada:

    • En la función, this hace referencia al documento que la operación map-reduce está procesando.

    • Para cada artículo, la función asocia el sku con un nuevo objeto value que contiene el count de 1 y el artículo qty para el pedido y emite el sku (almacenado en el key) y el value.

    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);
    }
    };
  2. Define la función de reducción correspondiente con dos argumentos keySKU y countObjVals:

    • countObjVals es una matriz cuyos elementos son los objetos asignados a los valores agrupados keySKU pasados ​​por la función de mapa a la función reductora.

    • La función reduce la matriz countObjVals a un solo objeto reducedValue que contiene los campos count y qty.

    • En reducedVal, el campo count contiene la suma de los count campos de los elementos individuales de la matriz, y el campo qty contiene la suma de los qty campos 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;
    };
  3. Define una función de finalización con dos argumentos key y reducedVal. La función modifica el objeto reducedVal para añadir un campo calculado llamado avg y devuelve el objeto modificado:

    var finalizeFunction2 = function (key, reducedVal) {
    reducedVal.avg = reducedVal.qty/reducedVal.count;
    return reducedVal;
    };
  4. Realice la operación map-reduce en la colección orders utilizando las funciones mapFunction2, reduceFunction2 y finalizeFunction2:

    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 query para seleccionar solo los documentos con un valor ord_date mayor o igual a new Date("2020-03-01"). Luego, envía los resultados a una colección map_reduce_example2.

    Si la colección map_reduce_example2 ya 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.

  5. Consulta la colección map_reduce_example2 para 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 } }

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" } }
] )
  1. La etapa selecciona solo aquellos documentos $match con ord_date mayor o igual new Date("2020-03-01") a.

  2. La etapa desglosa el documento por $unwind el items campo 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" }
    ...
  3. La etapa $group items.sku se agrupa por, calculando para cada SKU:

    • El campo qty. El campo qty contiene el
      total qty pedidos por cada items.sku $sum(Ver).
    • La matriz orders_ids. El campo orders_ids contiene un
      matriz de órdenes distintos _id para el items.sku $addToSet(ver).
    { "_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 ] }
  4. La etapa modifica el documento de salida para reflejar la salida de map-reduce y tener dos $project campos:_id valuey. La $project etapa establece:

  5. La etapa desglosa el documento por $unwind el items campo 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" }
    ...
  6. La etapa $group items.sku se agrupa por, calculando para cada SKU:

    { "_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 ] }
  7. La etapa modifica el documento de salida para reflejar la salida de map-reduce y tener dos $project campos:_id valuey. La $project etapa establece:

    • el value.count al tamaño de la orders_ids matriz $size utilizando.

    • el campo value.qty al qty del documento de entrada.

    • el value.avg al 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 } }
  8. Finalmente, escribe la salida en $merge la agg_alternative_3 colección. Si un documento existente tiene la misma clave _id que 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.

  9. Consulta la colección agg_alternative_3 para 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.

Para obtener más información y ejemplos, consulte la página Map-Reduce y Realizar Map-Reduce incremental.

Si configura el parámetro out para escribir los resultados en una colección, el comando devuelve un documento con el siguiente mapReduce formato:

{ "result" : "map_reduce_example", "ok" : 1 }

Si configura el parámetro out para mostrar los resultados en línea, el comando devuelve un documento con el siguiente mapReduce formato:

{
"results" : [
{
"_id" : <key>,
"value" :<reduced or finalizedValue for key>
},
...
],
"ok" : <int>
}
mapReduce.result

Para la salida enviada a una colección, este valor es:

  • una cadena para el nombre de la colección si no se especificó el nombre de la base de datos, o

  • un documento con db collection campos y si se especifican tanto un nombre de base de datos como un nombre de colección.

mapReduce.results

Para la salida escrita en línea, una matriz de documentos resultantes. Cada documento resultante contiene dos campos:

  • _id El campo contiene el valor key,

  • value El campo contiene el valor reducido o finalizado para el key asociado.

mapReduce.ok

Un valor de 1 indica que el comando se ejecutó correctamente. Un valor mapReduce de 0 indica un error.

Además de los campos de retorno específicos del comando mencionados anteriormente, incluye información db.runCommand() adicional:

  • para conjuntos de réplicas: $clusterTime y operationTime.

  • para clústeres fragmentados: operationTime y $clusterTime.

Se puede consultar db.runCommand Response para obtener más información sobre estos campos.

Volver

insert

En esta página