注意
作为 Map-Reduce 替代方案的聚合管道
从MongoDB 5.0开始, map-reduce已弃用:
您应该使用聚合管道,而不是 map-reduce。聚合管道提供比 map-reduce 更好的性能和可用性。
对于需要自定义功能的 map-reduce 操作,可以使用
$accumulator和$function聚合操作符。可以使用这些操作符在 JavaScript 中定义自定义聚合表达式。
有关 map-reduce 的聚合管道替代方案的示例,请参阅:
定义
mapReducemapReduce命令允许您对集合运行map-reduce聚合操作。提示
在
mongosh中,该命令也可通过mapReduce()辅助方法运行。辅助方法对
mongosh用户来说很方便,但它们返回的信息级别可能与数据库命令不同。如果不追求方便或需要额外的返回字段,请使用数据库命令。
兼容性
此命令可用于以下环境中托管的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
重要
M0 和 Flex 集群不支持此命令。有关更多信息,请参阅不支持的命令。
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
注意
该命令具有以下语法:
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> } )
命令字段
命令将以下字段作为参数:
字段 | 类型 | 说明 | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
字符串 | 要对其执行 map-reduce 的集合的名称。此集合在由 视图不支持 map-reduce 操作。 | |||||||||||
JavaScript 或字符串 | 一个 JavaScript 函数,用于将 有关更多信息,请参阅 map 函数的要求。 | |||||||||||
JavaScript 或字符串 | 一个 JavaScript 函数,可将与特定 | |||||||||||
字符串或文档 | ||||||||||||
文档 | 可选。使用查询运算符指定选择标准,确定输入到 | |||||||||||
文档 | 可选。对输入文档排序。此选项对于优化非常有用。例如,将排序键指定为与发出键相同,这样可减少 reduce 操作。排序键必须位于此集合的现有索引中。 | |||||||||||
数字 | 可选。指定输入到 | |||||||||||
JavaScript 或字符串 | 可选。一个 JavaScript 函数,用于修改 有关更多信息,请参阅 finalize 函数的要求。 | |||||||||||
文档 | 可选。指定可在 | |||||||||||
布尔 | 可选。指定是否在计算 默认值为 如果为
如果为
| |||||||||||
布尔 | ||||||||||||
布尔 | ||||||||||||
文档 | 可选。 指定用于操作的排序规则。 排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。 排序规则选项的语法如下: 指定排序规则时, 如果未指定排序规则,但集合具有默认排序规则(请参阅 如果没有为收集或操作指定排序规则,MongoDB 将使用先前版本中使用的简单二进制比较来进行字符串比较。 您不能为一个操作指定多个排序规则。例如,您不能为每个字段指定不同的排序规则,或者如果执行带排序的查找,则不能使用一种排序规则进行查找而另一种排序规则进行排序。 | |||||||||||
| non-negative integer | 可选。 指定时间限制(以毫秒为单位)。如果您未指定 MongoDB 使用与 | ||||||||||
文档 | 可选。一种文档,表示输出到集合时要使用的写关注。省略以使用默认的写关注。 | |||||||||||
| any | 可选。用户提供的待附加到该命令的注释。设置后,该注释将与该命令的记录一起出现在以下位置:
注释可以是任何有效的 BSON 类型(字符串、整型、对象、数组等)。 |
使用
下面是 mapReduce 命令的原型用法:
var mapFunction = function() { ... }; var reduceFunction = function(key, values) { ... }; db.runCommand( { mapReduce: <input-collection>, map: mapFunction, reduce: reduceFunction, out: { merge: <output-collection> }, query: <query> } )
注意
MongoDB 中的 JavaScript
map函数的要求
map 函数负责将每个输入文档转换为零个或多个文档。它可以访问 scope 参数中定义的变量,并具有以下原型:
function() { ... emit(key, value); }
map 函数具有以下要求:
在
map函数中,将当前文档引用为函数内的this。map函数不应 出于任何原因访问数据库。map函数应该是纯函数,或者对函数外部没有影响(即副作用)。map函数可以选择调用emit(key,value)任意次,以创建将key与value关联的输出文档。
以下 map 函数将调用 emit(key,value) 0 次或 1 次,具体取决于输入文档的 status 字段的值:
function() { if (this.status == 'A') emit(this.cust_id, 1); }
以下 map 函数可能会多次调用 emit(key,value) ,具体取决于输入文档的 items 字段中的元素数量:
function() { this.items.forEach(function(item){ emit(item.sku, 1); }); }
reduce函数的要求
reduce 函数具有以下原型:
function(key, values) { ... return result; }
reduce 函数表现出以下行为:
reduce函数不应访问数据库,即使是执行读操作也是如此。reduce函数不应 影响外部系统。MongoDB 可以针对同一键多次调用
reduce函数。在这种情况下,该键的reduce函数的先前输出将成为该键的下一个reduce函数调用的输入值之一。reduce函数可以访问scope参数中定义的变量。reduce的输入不得大于 MongoDB 最大 BSON 文档大小的一半。当返回大型文档并在后续的reduce步骤中将其连接在一起时,可能会违反此要求。
由于可以针对同一键多次调用 reduce 函数,因此以下属性必须为 true:
返回对象的类型必须与
map函数发出的value的类型相同。reduce函数必须是关联函数。以下语句必须为 true:reduce(key, [ C, reduce(key, [ A, B ]) ] ) == reduce( key, [ C, A, B ] ) reduce函数必须是幂等的。确保以下语句为 true:reduce( key, [ reduce(key, valuesArray) ] ) == reduce( key, valuesArray ) reduce函数应该是可交换的:也就是说,valuesArray中元素的顺序不应影响reduce函数的输出,因此以下语句成立:reduce( key, [ A, B ] ) == reduce( key, [ B, A ] )
finalize函数的要求
finalize 函数具有以下原型:
function(key, reducedValue) { ... return modifiedObject; }
finalize 函数接收 key 值和来自 reduce 函数的 reducedValue 作为其参数。请注意:
finalize函数不应 出于任何原因访问数据库。finalize函数应该是纯函数,或者对函数外部没有影响(即副作用)。finalize函数可以访问scope参数中定义的变量。
out 选项
您可以为 out 参数指定以下选项:
输出到集合
此选项输出到新集合,并且在副本集的从节点上不可用。
out: <collectionName>
输出到具有操作的集合
注意
从版本 4.2 开始,MongoDB 弃用了:
用于创建新的分片集合的 map-reduce 选项,以及对 map-reduce 使用分片选项。要输出到分片集合,请首先创建分片集合。MongoDB 4.2 还弃用了替换现有分片集合的功能。
仅当将已存在的集合传递给 out 时,此选项才可用。它不适用于副本集的从节点。
out: { <action>: <collectionName> [, db: <dbName>] [, sharded: <boolean> ] }
当使用操作输出到集合时,out 具有以下参数:
<action>:指定以下操作之一:replace如果存在具有
<collectionName>的集合,则替换<collectionName>的内容。merge如果输出集合已经存在,则将新结果与现有结果合并。如果现有文档与新结果具有相同的键,则覆盖该现有文档。
reduce如果输出集合已经存在,则将新结果与现有结果合并。如果现有文档与新结果具有相同的键,请将
reduce函数应用于新文档和现有文档,并使用结果覆盖现有文档。
db:可选。您希望 map-Reduce 操作写入其输出的数据库的名称。默认情况下,这将是与输入集合相同的数据库。
输出内联
在内存中执行 map-reduce 操作并返回结果。此选项是副本集的从节点上 out 的唯一可用选项。
out: { inline: 1 }
结果必须符合 BSON 文档的最大大小。
必需的访问权限
如果您的 MongoDB 部署强制进行身份验证,则执行 mapReduce 命令的用户必须拥有以下权限操作:
带有 {out : inline} 输出选项的 map-reduce:
输出到集合时使用 replace 操作执行 Map-reduce:
输出到集合时使用 merge 或 reduce 操作执行 Map-reduce:
readWrite 内置角色为执行 map-reduce 聚合提供了必要的权限。
限制
mapReduce 命令不再支持 afterClusterTime。因此,mapReduce 不能与因果一致的会话相关联。
Map-Reduce 示例
在 mongosh 中,db.collection.mapReduce() 方法是 mapReduce 命令的封装器。以下示例使用 db.collection.mapReduce() 方法:
本节中的示例包括不带自定义聚合表达式的聚合管道替代方案。有关使用自定义表达式的替代方案,请参阅Map-Reduce 到聚合管道转换示例。
创建一个包含以下文档的样本集合 orders:
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" } ])
返回每位客户的总价
针对 orders 集合执行 map-reduce 操作会按 cust_id 进行分组,并为每个 cust_id 计算 price 之和:
定义 Map 函数来处理每个输入文档:
在函数中,
this指的是 Map-Reduce 操作正在处理的文档。该函数将每个文档的
price映射到cust_id,并输出cust_id和price。
var mapFunction1 = function() { emit(this.cust_id, this.price); }; 使用两个参数
keyCustId和valuesPrices定义相应的 Reduce 函数:valuesPrices是一个数组,其元素是由 Map 函数发出并按keyCustId分组的price值。该函数将
valuesPrice数组缩减为其元素之和。
var reduceFunction1 = function(keyCustId, valuesPrices) { return Array.sum(valuesPrices); }; 使用
mapFunction1Map 函数和reduceFunction1Reduce 函数对orders集合中的所有文档执行 Map-Reduce:db.orders.mapReduce( mapFunction1, reduceFunction1, { out: "map_reduce_example" } ) 此操作将结果输出到名为
map_reduce_example的集合。如果map_reduce_example集合已存在,该操作将用此 Map-Reduce 操作的结果替换其内容。查询
map_reduce_example集合以验证结果: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 }
聚合替代方案
利用可用的聚合管道操作符,您可以重写 Map-Reduce 操作,而无需定义自定义函数:
db.orders.aggregate([ { $group: { _id: "$cust_id", value: { $sum: "$price" } } }, { $out: "agg_alternative_1" } ])
$group阶段按cust_id分组并计算value字段(另见$sum)。value字段包含每个cust_id的price总额。此阶段将以下文档输出到下一阶段:
{ "_id" : "Don Quis", "value" : 155 } { "_id" : "Ant O. Knee", "value" : 95 } { "_id" : "Cam Elot", "value" : 60 } { "_id" : "Busby Bee", "value" : 125 } 查询
agg_alternative_1集合以验证结果:db.agg_alternative_1.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 }
提示
有关使用自定义聚合表达式的替代方案,请参阅 Map-Reduce 到聚合管道转换示例。
通过每款商品的平均数量计算订单和总数量
在以下示例中,您将看到针对 ord_date 值大于或等于 2020-03-01 的所有文档对 orders 集合执行的 Map-Reduce 操作。
示例中的操作:
按
item.sku字段分组,计算每个sku的订单数量和总订购量。计算每个
sku值的每个订单的平均数量,并将结果合并到输出集合中。
合并结果时,如果现有文档与新结果具有相同的键,则该操作将覆盖现有文档。如果没有具有相同键的现有文档,操作将插入该文档。
步骤示例:
定义 Map 函数来处理每个输入文档:
在函数中,
this指的是 Map-Reduce 操作正在处理的文档。对于每款商品,该函数将
sku与新对象value关联,该对象包含1的count和订单的商品qty,并发出sku(存储在key中)和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); } }; 使用两个参数
keySKU和countObjVals定义相应的 Reduce 函数:countObjVals是一个数组,其元素是映射到分组keySKU值的对象,这些值由 Map 函数传递到 Reducer 函数。该函数将
countObjVals数组缩减为包含count和qty字段的单个对象reducedValue。在
reducedVal中,count字段包含各个数组元素中count字段的总和,而qty字段包含各个数组元素中qty字段的总和。
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; }; 使用两个参数
key和reducedVal定义 finalize 函数。该函数会修改reducedVal对象以添加名为avg的计算字段并返回修改后的对象:var finalizeFunction2 = function (key, reducedVal) { reducedVal.avg = reducedVal.qty/reducedVal.count; return reducedVal; }; 使用
mapFunction2、reduceFunction2和finalizeFunction2函数对orders集合执行 Map-Reduce 操作:db.orders.mapReduce( mapFunction2, reduceFunction2, { out: { merge: "map_reduce_example2" }, query: { ord_date: { $gte: new Date("2020-03-01") } }, finalize: finalizeFunction2 } ); 此操作使用
query字段来仅选择ord_date大于或等于new Date("2020-03-01")的文档。然后它将结果输出到集合map_reduce_example2。如果
map_reduce_example2集合已存在,该操作会将现有内容与此 Map-Reduce 操作的结果合并。即,如果现有文档的键与新结果相同,则操作会覆盖现有文档。如果没有具有相同键的现有文档,操作将插入该文档。查询
map_reduce_example2集合以验证结果:db.map_reduce_example2.find().sort( { _id: 1 } ) 该操作会返回以下文档:
{ "_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 } }
聚合替代方案
利用可用的聚合管道操作符,您可以重写 Map-Reduce 操作,而无需定义自定义函数:
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" } } ] )
$match阶段仅选择ord_date大于等于new Date("2020-03-01")的文档。$unwind阶段按items数组字段对文档进行分解,为每个数组元素输出一个文档。例如:{ "_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" } ... $group阶段按items.sku分组,针对每个 sku 进行计算:qty字段。qty字段包含- 每个
items.sku的订购qty总计(参见$sum)。
orders_ids数组。orders_ids字段包含一个items.sku的不同顺序_id的数组(参见$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 ] } $project阶段会重塑输出文档以镜像 Map-Reduce 的输出,使其具有两个字段_id和value。$project会:$unwind阶段按items数组字段对文档进行分解,为每个数组元素输出一个文档。例如:{ "_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" } ... $group阶段按items.sku分组,针对每个 sku 进行计算:qty字段。qty字段包含使用$sum为每个items.sku订购的qty总计。orders_ids数组。orders_ids字段包含使用$addToSet的items.sku的不同顺序_id的数组。
{ "_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 ] } $project阶段会重塑输出文档以镜像 Map-Reduce 的输出,使其具有两个字段_id和value。$project会:使用
$size将value.count设置为orders_ids数组的大小将
value.qty设置为输入文档中的qty字段。
{ "_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 } } 最后,
$merge将输出写入集合agg_alternative_3。如果现有文档的键_id与新结果相同,则操作会覆盖现有文档。如果没有具有相同键的现有文档,操作将插入该文档。查询
agg_alternative_3集合以验证结果:db.agg_alternative_3.find().sort( { _id: 1 } ) 该操作将返回以下文档:
{ "_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 } }
提示
有关使用自定义聚合表达式的替代方案,请参阅 Map-Reduce 到聚合管道转换示例。
有关更多信息和示例,请参阅 Map-Reduce 页面和执行增量 Map-Reduce
输出
如果将 out 参数设置为将结果写入集合,mapReduce 命令将以如下形式返回文档:
{ "result" : "map_reduce_example", "ok" : 1 }
如果将 out 参数设置为以内联方式输出结果,mapReduce 命令将返回以下格式的文档:
{ "results" : [ { "_id" : <key>, "value" :<reduced or finalizedValue for key> }, ... ], "ok" : <int> }
mapReduce.ok值为
1表示mapReduce命令运行成功。值为0表示出现错误。
除了上述特定的命令返回字段外,db.runCommand() 还包括其他信息:
对于副本集:
$clusterTime和operationTime。对于分片集群:
operationTime和$clusterTime。
有关这些字段的详细信息,请参阅 db.runCommand Response。