Redução de mapa
Nesta página
Observação
Pipeline de Agregação como Alternativa à Redução de Mapa
A partir do MongoDB 5.0, map-reduce está obsoleto:
Em vez de map-reduce, você deve usar um aggregation pipeline. aggregation pipeline fornece melhor desempenho e usabilidade do que a redução de mapa.
Você pode reescrever operações de map-reduce utilizando aggregation pipeline stages, como
$group
,$merge
e outros.Nas operações de map-reduce que exigem funcionalidade personalizada, você pode usar os operadores de agregação
$accumulator
e$function
. Você pode usar esses operadores para definir expressões de agregação personalizadas no JavaScript.
Para obter exemplos de alternativas de aggregation pipeline para map-reduce, consulte:
Definição
mapReduce
The
mapReduce
command allows you to run Mapear-Reduzir aggregation operations over a collection.Dica
Em
mongosh
, esse comando também pode ser executado por meio do método auxiliarmapReduce()
.Os métodos auxiliares são práticos para os usuários
mongosh
, mas podem não retornar o mesmo nível de informações que os comandos do banco de dados. Nos casos em que a praticidade não for necessária ou os campos de retorno adicionais forem necessários, use o comando de banco de dados.
Compatibilidade
Esse comando está disponível em implantações hospedadas nos seguintes ambientes:
MongoDB Atlas: o serviço totalmente gerenciado para implantações do MongoDB na nuvem
Importante
Este comando não é suportado em clusters M0, M2 e M5 . Para obter mais informações, consulte Comandos não suportados.
MongoDB Enterprise: a versão autogerenciada e baseada em assinatura do MongoDB
MongoDB Community: uma versão com código disponível, de uso gratuito e autogerenciada do MongoDB
Sintaxe
Observação
MongoDB ignores the verbose option.
Starting in version 4.2, MongoDB deprecates:
The map-reduce option to criar a new sharded collection as well as the use of the sharded option for map-reduce. To output to a sharded collection, create the sharded collection first. MongoDB 4.2 also deprecates the replacement of an existing sharded collection.
O comando tem a seguinte sintaxe:
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> } )
Campos de comando
The command takes the following fields as arguments:
Campo | Tipo | Descrição | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
string | The name of the collection on which you want to perform map-reduce.
This collection will be filtered using As visualizações não suportam operações de redução de mapa. | |||||||||||
JavaScript or String | A JavaScript function that associates or "maps" a For more information, see Requirements for the map Function. | |||||||||||
JavaScript or String | A JavaScript function that "reduces" to a single object all
the For more information, see Requirements for the reduce Function. | |||||||||||
string ou documento | Specifies where to output the result of the map-reduce operation. You can either output to a collection or return the result inline. On a Principal member of a replica set you can output either to a collection or inline, but on a secundário, only inline output is possible. For more information, see out Options. | |||||||||||
documento | Optional. Specifies the selection criteria using query operators for determining the documents
input to the | |||||||||||
documento | Optional. Sorts the Entrada documents. This option is useful for optimization. For example, specify the sort key to be the same as the emit key so that there are fewer reduce operations. The sort key must be in an existing index for this collection. | |||||||||||
número | Optional. Specifies a maximum number of documents for the input into the
| |||||||||||
JavaScript or String | Optional. A JavaScript function that modifies the output after
the For more information, see Requirements for the finalize Function. | |||||||||||
documento | Optional. Specifies global variables that are accessible in the | |||||||||||
booleano | Optional. Specifies whether to convert intermediate data into BSON
format between the execution of the Padrão é Se
Se
| |||||||||||
booleano | Optional. Specifies whether to include the Padrão é This option is ignored. The result
information always excludes the | |||||||||||
booleano | Optional. Enables If the output option is set to
| |||||||||||
documento | Opcional. Especifica o agrupamento a ser usado para a operação. A colocação permite que os usuários especifiquem regras específicas do idioma para comparação de strings, como regras para letras maiúsculas e marcas de acento. A opção de agrupamento tem a seguinte sintaxe:
Ao especificar agrupamento, o campo Se o agrupamento não for especificado, mas a coleção tiver um agrupamento padrão (consulte Se nenhum agrupamento for especificado para a coleção ou para as operações, o MongoDB usa a comparação binária simples usada nas versões anteriores para comparações de strings. Você não pode especificar vários agrupamentos para uma operação. Por exemplo, você não pode especificar agrupamentos diferentes por campo ou, se estiver realizando uma busca com uma classificação, não poderá usar um agrupamento para a busca e outro para a classificação. | |||||||||||
| non-negative integer | Opcional. Especifica um limite de tempo em milissegundos. Se você não especificar um valor para O MongoDB encerra as operações que excedem o limite de tempo alocado usando o mesmo mecanismo de | ||||||||||
documento | Optional. A document that expresses the Escreva preocupação to use when outputting to a collection. Omit to use the default write concern. | |||||||||||
| any | Opcional. Um comentário fornecido pelo usuário para anexar a este comando. Depois de definido, esse comentário aparece junto com os registros desse comando nos seguintes locais:
Um comentário pode ser qualquer tipo BSON válido (string, inteiro, objeto, array etc). |
Uso
The following is a prototype usage of the mapReduce
command:
var mapFunction = function() { ... }; var reduceFunction = function(key, values) { ... }; db.runCommand( { mapReduce: <input-collection>, map: mapFunction, reduce: reduceFunction, out: { merge: <output-collection> }, query: <query> } )
Observação
JavaScript no MongoDB
Although mapReduce
uses JavaScript, most
interactions with MongoDB do not use JavaScript but use an
idiomatic driver in the language
of the interacting application.
Requirements for the map
Function
The map
function is responsible for transforming each input document into
zero or more documents. It can access the variables defined in the scope
parameter, and has the following prototype:
function() { ... emit(key, value); }
The map
function has the following requirements:
In the
map
function, reference the current document asthis
within the function.The
map
function should não access the database for any reason.The
map
function should be pure, or have no impact outside of the function (i.e. side effects.)The
map
function may optionally callemit(key,value)
any number of times to create an output document associatingkey
withvalue
.
The following map
function will call emit(key,value)
either
0 or 1 times depending on the value of the input document's
status
field:
function() { if (this.status == 'A') emit(this.cust_id, 1); }
The following map
function may call emit(key,value)
multiple times depending on the number of elements in the input
document's items
field:
function() { this.items.forEach(function(item){ emit(item.sku, 1); }); }
Requirements for the reduce
Function
The reduce
function has the following prototype:
function(key, values) { ... return result; }
The reduce
function exhibits the following behaviors:
The
reduce
function should não access the database, even to perform read operations.The
reduce
function should não affect the outside system.MongoDB can invoke the
reduce
function more than once for the same key. In this case, the previous output from thereduce
function for that key will become one of the input values to the nextreduce
function invocation for that key.The
reduce
function can access the variables defined in thescope
parameter.The inputs to
reduce
must not be larger than half of MongoDB's maximum BSON document size. This requirement may be violated when large documents are returned and then joined together in subsequentreduce
steps.
Because it is possible to invoke the reduce
function
more than once for the same key, the following
properties need to be true:
the type of the return object must be identical to the type of the
value
emitted by themap
function.the
reduce
function must be associative. The following statement must be true:reduce(key, [ C, reduce(key, [ A, B ]) ] ) == reduce( key, [ C, A, B ] ) the
reduce
function must be idempotent. Ensure that the following statement is true:reduce( key, [ reduce(key, valuesArray) ] ) == reduce( key, valuesArray ) the
reduce
function should be commutative: that is, the order of the elements in thevaluesArray
should not affect the output of thereduce
function, so that the following statement is true:reduce( key, [ A, B ] ) == reduce( key, [ B, A ] )
Requirements for the finalize
Function
The finalize
function has the following prototype:
function(key, reducedValue) { ... return modifiedObject; }
The finalize
function receives as its arguments a key
value and the reducedValue
from the reduce
function. Be
aware that:
The
finalize
function should não access the database for any reason.The
finalize
function should be pure, or have no impact outside of the function (i.e. side effects.)The
finalize
function can access the variables defined in thescope
parameter.
out
Opções
You can specify the following options for the out
parameter:
Output to a Collection
This option outputs to a new collection, and is not available on secondary members of replica sets.
out: <collectionName>
Output to a Collection with an Action
Observação
Starting in version 4.2, MongoDB deprecates:
The map-reduce option to criar a new sharded collection as well as the use of the sharded option for map-reduce. To output to a sharded collection, create the sharded collection first. MongoDB 4.2 also deprecates the replacement of an existing sharded collection.
This option is only available when passing a collection that
already exists to out
. It is not available
on secondary members of replica sets.
out: { <action>: <collectionName> [, db: <dbName>] [, sharded: <boolean> ] }
When you output to a collection with an action, the out
has the
following parameters:
<action>
: Specify one of the following actions:replace
Replace the contents of the
<collectionName>
if the collection with the<collectionName>
exists.merge
Merge the new result with the existing result if the output collection already exists. If an existing document has the same key as the new result, overwrite that existing document.
reduce
Merge the new result with the existing result if the output collection already exists. If an existing document has the same key as the new result, apply the
reduce
function to both the new and the existing documents and overwrite the existing document with the result.
db
:Optional. The name of the database that you want the map-reduce operation to write its output. By default this will be the same database as the input collection.
Output Inline
Perform the map-reduce operation in memory and return the result. This
option is the only available option for out
on secondary members of
replica sets.
out: { inline: 1 }
The result must fit within the maximum size of a BSON document.
Acesso necessário
If your MongoDB deployment enforces authentication, the user executing
the mapReduce
command must possess the following
privilege actions:
Map-reduce with {out : inline}
output option:
Map-reduce with the replace
action when outputting to a
collection:
Map-reduce with the merge
or reduce
actions when
outputting to a collection:
The readWrite
built-in role provides the necessary
permissions to perform map-reduce aggregation.
Restrições
O comando mapReduce
não mais compatível com afterClusterTime. Então, mapReduce
não pode ser associada a sessões causalmente consistentes.
Exemplos de map-reduce
In mongosh
, the db.collection.mapReduce()
method is a wrapper around the mapReduce
command. The
following examples use the db.collection.mapReduce()
method:
Os exemplos nesta seção incluem alternativas de aggregation pipelines sem expressões de agregação customizadas. Para alternativas que usam expressões personalizadas, consulte Exemplos de tradução do map-reduce para o aggregation pipeline.
Crie uma coleção de amostra orders
com estes 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" } ])
Retornar o preço total por cliente
Execute a operação map-reduce na collection orders
para agrupar pelo cust_id
e calcule a soma do price
para cada cust_id
:
Defina a função do mapa para processar cada documento de entrada:
Na função, o
this
refere-se ao documento que a operação de redução de mapa está processando.A função mapeia o
price
para ocust_id
para cada documento e emite ocust_id
eprice
.
var mapFunction1 = function() { emit(this.cust_id, this.price); }; Defina a função de redução correspondente com dois argumentos
keyCustId
evaluesPrices
:O
valuesPrices
é uma array cujos elementos são os valoresprice
emitidos pela função de mapa e agrupados porkeyCustId
.A função reduz a array
valuesPrice
à soma de seus elementos.
var reduceFunction1 = function(keyCustId, valuesPrices) { return Array.sum(valuesPrices); }; Executar a redução de mapa em todos os documentos na coleção do
orders
utilizando a função de mapa domapFunction1
e a função de redução doreduceFunction1
:db.orders.mapReduce( mapFunction1, reduceFunction1, { out: "map_reduce_example" } ) Esta operação gera resultados para uma coleção denominada
map_reduce_example
. Se a coleçãomap_reduce_example
já existir, a operação substituirá o conteúdo pelos resultados desta operação de redução de mapa.Consulte a coleção
map_reduce_example
para verificar os resultados:db.map_reduce_example.find().sort( { _id: 1 } ) A operação retorna estes documentos:
{ "_id" : "Ant O. Knee", "value" : 95 } { "_id" : "Busby Bee", "value" : 125 } { "_id" : "Cam Elot", "value" : 60 } { "_id" : "Don Quis", "value" : 155 }
Alternativa de aggregation
Usando os operadores de aggregation pipeline disponíveis, você pode reescrever a operação de map-reduce sem definir funções personalizadas:
db.orders.aggregate([ { $group: { _id: "$cust_id", value: { $sum: "$price" } } }, { $out: "agg_alternative_1" } ])
O estágio
$group
agrupa pelocust_id
e calcula o campovalue
(consulte também$sum
). O campovalue
contém o total deprice
para cadacust_id
.O estágio envia os seguintes documentos para o próximo estágio:
{ "_id" : "Don Quis", "value" : 155 } { "_id" : "Ant O. Knee", "value" : 95 } { "_id" : "Cam Elot", "value" : 60 } { "_id" : "Busby Bee", "value" : 125 } Em seguida, o
$out
grava a saída na coleçãoagg_alternative_1
. Alternativamente, você pode utilizar$merge
ao invés de$out
.Consulte a coleção
agg_alternative_1
para verificar os resultados:db.agg_alternative_1.find().sort( { _id: 1 } ) A operação retorna os seguintes documentos:
{ "_id" : "Ant O. Knee", "value" : 95 } { "_id" : "Busby Bee", "value" : 125 } { "_id" : "Cam Elot", "value" : 60 } { "_id" : "Don Quis", "value" : 155 }
Dica
Veja também:
Para obter uma alternativa que usa expressões de agregação personalizadas, consulte Map-Reduce to Aggregation Pipeline Translation Examples.
Calcule o pedido e a quantidade total com a quantidade média por item
No exemplo seguinte, você visualizará uma operação de map-reduce na collection orders
para todos os documentos que têm um valor ord_date
maior ou igual a 2020-03-01
.
A operação no exemplo:
Agrupa pelo campo
item.sku
e calcula o número de pedidos e a quantidade total solicitada para cadasku
.Calcula a quantidade média por pedido para cada valor
sku
e mescla os resultados na coleta de saída.
Ao mesclar resultados, se um documento existente tiver a mesma chave que o novo resultado, a operação substituirá o documento existente. Se não houver nenhum documento existente com a mesma chave, a operação inserirá o documento.
Etapas de exemplo:
Defina a função do mapa para processar cada documento de entrada:
Na função, o
this
refere-se ao documento que a operação de redução de mapa está processando.Para cada item, a função associa o
sku
a um novo objetovalue
que contém ocount
de1
e o itemqty
para o pedido e emite osku
(armazenado nokey
) e ovalue
.
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); } }; Defina a função de redução correspondente com dois argumentos
keySKU
ecountObjVals
:countObjVals
é um array cujos elementos são os objetos mapeados para os valores agrupados dokeySKU
passados pela função de mapa para a função de redução.A função reduz a matriz
countObjVals
para um único objetoreducedValue
que contém os camposcount
eqty
.Em
reducedVal
, o campocount
contém a soma dos camposcount
dos elementos individuais da array e o campoqty
contém a soma dos camposqty
dos elementos individuais da array.
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; }; Defina uma função de finalização com dois argumentos
key
ereducedVal
. A função modifica o objetoreducedVal
para adicionar um campo calculado denominadoavg
e retorna o objeto modificado:var finalizeFunction2 = function (key, reducedVal) { reducedVal.avg = reducedVal.qty/reducedVal.count; return reducedVal; }; Execute a operação de redução de mapa na coleção do
orders
utilizando as funçõesmapFunction2
,reduceFunction2
efinalizeFunction2
:db.orders.mapReduce( mapFunction2, reduceFunction2, { out: { merge: "map_reduce_example2" }, query: { ord_date: { $gte: new Date("2020-03-01") } }, finalize: finalizeFunction2 } ); Esta operação utiliza o campo
query
para selecionar apenas os documentos comord_date
maior ou igual anew Date("2020-03-01")
. Em seguida, ele envia os resultados para uma coleçãomap_reduce_example2
.Se a coleção
map_reduce_example2
já existir, a operação fundirá o conteúdo existente com os resultados desta operação de redução de mapa. Ou seja, se um documento existente tiver a mesma chave que o novo resultado, a operação substituirá o documento existente. Se não houver nenhum documento existente com a mesma chave, a operação inserirá o documento.Consulte a coleção
map_reduce_example2
para verificar os resultados:db.map_reduce_example2.find().sort( { _id: 1 } ) A operação retorna estes 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 aggregation
Usando os operadores de aggregation pipeline disponíveis, você pode reescrever a operação de map-reduce sem definir funções 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" } } ] )
A etapa
$match
seleciona apenas os documentos comord_date
maior ou igual anew Date("2020-03-01")
.O estágio
$unwind
divide o documento pelo campo de arrayitems
para gerar um documento para cada elemento da array. Por exemplo:{ "_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" } ... Os
$group
grupos de estágio peloitems.sku
, calculando para cada sku:- O campo
qty
. O campoqty
contém o - total
qty
solicitado por cadaitems.sku
(consulte$sum
).
- O campo
- A matriz
orders_ids
. O campoorders_ids
contém um - array de
_id
de ordem distinta para oitems.sku
(veja$addToSet
).
- A 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 ] } O estágio
$project
remodela o documento de saída para espelhar a saída do map-reduce para ter dois campos_id
evalue
. Os conjuntos$project
:O estágio
$unwind
divide o documento pelo campo de arrayitems
para gerar um documento para cada elemento da array. Por exemplo:{ "_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" } ... Os
$group
grupos de estágio peloitems.sku
, calculando para cada sku:O campo
qty
. O campoqty
contém o total deqty
ordenados por cadaitems.sku
utilizando$sum
.A array
orders_ids
. O campoorders_ids
contém uma array de ordem distinta_id
para oitems.sku
utilizando$addToSet
.
{ "_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 ] } O estágio
$project
remodela o documento de saída para espelhar a saída do map-reduce para ter dois campos_id
evalue
. Os conjuntos$project
:o
value.count
para o tamanho da arrayorders_ids
usando$size
.o
value.qty
para o campoqty
do documento de entrada.o
value.avg
para o número médio de quantidade por pedido usando$divide
e$size
.
{ "_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, o
$merge
grava a saída na coleçãoagg_alternative_3
. Se um documento existente tiver a mesma chave_id
que o novo resultado, a operação substituirá o documento existente. Se não houver nenhum documento existente com a mesma chave, a operação inserirá o documento.Consulte a coleção
agg_alternative_3
para verificar os resultados:db.agg_alternative_3.find().sort( { _id: 1 } ) A operação retorna os seguintes 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 } }
Dica
Veja também:
Para obter uma alternativa que usa expressões de agregação personalizadas, consulte Map-Reduce to Aggregation Pipeline Translation Examples.
For more information and examples, see the Map-Reduce page and Executar Redução incremental de mapa
Saída
If you set the out parameter to write the
results to a collection, the mapReduce
command returns a
document in the following form:
{ "result" : "map_reduce_example", "ok" : 1 }
If you set the out parameter to output the
results inline, the mapReduce
command returns a document
in the following form:
{ "results" : [ { "_id" : <key>, "value" :<reduced or finalizedValue for key> }, ... ], "ok" : <int> }
mapReduce.results
For output written inline, an array of resulting documents. Each resulting document contains two fields:
_id
field contains thekey
value,value
field contains the reduced or finalized value for the associatedkey
.
mapReduce.ok
A value of
1
indicates themapReduce
command ran successfully. A value of0
indicates an error.
In addition to the aforementioned command specific return fields, the
db.runCommand()
includes additional information:
for replica sets:
$clusterTime
, andoperationTime
.para clusters fragmentados:
operationTime
e$clusterTime
.
Consulte Resposta db.runCommand para obter detalhes sobre esses campos.