mapReduce

在本页面

db.runCommand(
               {
                 mapReduce: <collection>,
                 map: <function>,
                 reduce: <function>,
                 finalize: <function>,
                 out: <output>,
                 query: <document>,
                 sort: <document>,
                 limit: <number>,
                 scope: <document>,
                 jsMode: <boolean>,
                 verbose: <boolean>,
                 bypassDocumentValidation: <boolean>,
                 collation: <document>,
                 writeConcern: <document>
               }
             )

将集合的名称传递给mapReduce命令(即<collection>)以用作执行 Map 减少操作的源文档。

Note

Views不支持 map-reduce 操作。

该命令还接受以下参数:

Field Type Description
mapReduce collection 您要在其上执行 map-reduce 的集合的名称。该集合将由query过滤,然后由map函数处理。
map function 一个将valuekey关联或“Map”并发出key和值pair的 JavaScript 函数。


有关更多信息,请参见Map 功能要求
| reduce | function | JavaScript 函数,将与特定key关联的所有values“减少”到单个对象。
有关更多信息,请参见化简功能的要求
| out |字符串或文档|指定将 map-reduce 操作的结果输出到何处。您可以输出到集合,也可以内联返回结果。在副本集的primary成员上,您可以输出到集合或内联,但在secondary上,只能进行内联输出。
有关更多信息,请参见out Options
| query |文档|可选。使用query operators指定选择标准,以确定 Importing 到map功能的文档。
| sort |文档|可选。对* input *文档进行排序。此选项对于优化很有用。例如,将排序键指定为与运行键相同,以便减少还原操作。排序键必须在此集合的现有索引中。
| limit |数字|可选。指定用于 Importingmap函数的最大文档数。
| finalize |功能|可选。遵循reduce方法并修改输出。
有关更多信息,请参见完成功能的要求
| scope |文档|可选。指定可以在mapreducefinalize函数中访问的全局变量。
| jsMode |布尔值|可选。指定是否在执行mapreduce函数之间将中间数据转换为 BSON 格式。
默认为false
如果false
在内部,MongoDB 将map函数发出的 JavaScript 对象转换为 BSON 对象。然后,在调用reduce函数时,这些 BSON 对象将转换回 JavaScript 对象。
Map 减少操作将中间 BSON 对象放置在磁盘上的临时存储中。这允许 map-reduce 操作在任意大的数据集上执行。
如果true
在内部,在map函数期间发出的 JavaScript 对象保留为 JavaScript 对象。无需为reduce函数转换对象,这可以加快执行速度。
您只能对 Map 器的emit()函数使用少于 500,000 个不同的key参数的结果集使用jsMode
| verbose |布尔值|可选。指定是否在结果信息中包括timing信息。将verbose设置为true以包含timing信息。
默认为false
| bypassDocumentValidation |布尔值|可选。使mapReduce在操作过程中绕过文档验证。这使您可以插入不符合验证要求的文档。
3.2 版中的新功能。

Note





如果output option设置为inline,则不会出现document validation。如果输出进入集合,则mapReduce会遵守集合具有的验证规则,并且不会将任何无效文档插入,除非将bypassDocumentValidation参数设置为 true。



|
| collation |文档|可选。

> 指定用于操作的collation

> Collation允许用户为字符串比较指定特定于语言的规则,例如字母大写和重音符号的规则。

> 排序规则选项具有以下语法:

> collation: {

> locale: <string>,

> caseLevel: <boolean>,

> caseFirst: <string>,

> strength: <int>,

> numericOrdering: <boolean>,

> alternate: <string>,

> maxVariable: <string>,

> backwards: <boolean>

> }

> 指定排序规则时,locale字段为必填字段;所有其他排序规则字段都是可选的。有关字段的说明,请参见Collation Document

> 如果未指定排序规则,但是集合具有默认排序规则(请参见db.createCollection()),则该操作将使用为集合指定的排序规则。

> 如果没有为集合或操作指定排序规则,则 MongoDB 使用先前版本中使用的简单二进制比较进行字符串比较。

> 您不能为一个操作指定多个排序规则。例如,您不能为每个字段指定不同的排序规则,或者如果对排序执行查找,则不能对查找使用一种排序规则,而对排序使用另一种排序规则。

> 3.4 版中的新功能。
| writeConcern |文档|可选。表示要输出到集合时使用的write concern的文档。忽略使用默认的写关注。

以下是mapReduce命令的原型用法:

var mapFunction = function() { ... };
var reduceFunction = function(key, values) { ... };

db.runCommand(
               {
                 mapReduce: <input-collection>,
                 map: mapFunction,
                 reduce: reduceFunction,
                 out: { merge: <output-collection> },
                 query: <query>
               }
             )

JavaScript in MongoDB

尽管mapReduce使用 JavaScript,但是大多数与 MongoDB 的交互都不使用 JavaScript,而是使用idiomatic driver作为交互应用程序的语言。

Map 功能要求

map函数负责将每个 Importing 文档转换为零个或多个文档。它可以访问scope参数中定义的变量,并具有以下原型:

function() {
   ...
   emit(key, value);
}

map函数具有以下要求:

以下map函数将根据 Importing 文档的status字段的值调用emit(key,value) 0 或 1 次:

function() {
    if (this.status == 'A')
        emit(this.cust_id, 1);
}

以下map函数可能会多次调用emit(key,value),具体取决于 Importing 文档的items字段中的元素数量:

function() {
    this.items.forEach(function(item){ emit(item.sku, 1); });
}

reduce 函数的要求

reduce函数具有以下原型:

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

reduce函数具有以下行为:

因为可以为同一键多次调用reduce函数,所以以下属性必须为 true:

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

完成函数的要求

finalize函数具有以下原型:

function(key, reducedValue) {
   ...
   return modifiedObject;
}

finalize函数从reduce函数接收key值和reducedValue作为其参数。意识到:

out Options

您可以为out参数指定以下选项:

输出到集合

此选项输出到新集合,在副本集的辅助成员上不可用。

out: <collectionName>

通过操作输出到集合

仅当将已经存在的集合传递给out时,此选项才可用。在副本集的辅助成员上不可用。

out: { <action>: <collectionName>
        [, db: <dbName>]
        [, sharded: <boolean> ]
        [, nonAtomic: <boolean> ] }

当您通过操作输出到集合时,out具有以下参数:

如果存在带有<collectionName>的集合,请替换<collectionName>的内容。

如果输出集合已经存在,则将新结果与现有结果合并。如果现有文档的密钥与新结果相同,则“覆盖”该现有文档。

如果输出集合已经存在,则将新结果与现有结果合并。如果现有文档的键与新结果相同,则对新文档和现有文档都应用reduce函数,并用结果覆盖现有文档。

可选的。您希望 map-reduce 操作写入其输出的数据库的名称。默认情况下,该数据库将与 Importing 集合相同。

可选的。如果true 并且已在输出数据库上启用分片,则 map-reduce 操作将使用_id字段作为分片键对输出集合进行分片。

如果truecollectionName是现有的未分片集合,则 map-reduce 失败。

可选的。将输出操作指定为非原子操作。这仅适用于mergereduce输出模式,这可能需要几分钟才能执行。

默认情况下,nonAtomicfalse,并且 map-reduce 操作在后处理期间锁定数据库。

如果nonAtomictrue,则后处理步骤将阻止 MongoDB 锁定数据库:在此期间,其他 Client 端将能够读取输出集合的中间状态。

Output Inline

在内存中执行 map-reduce 操作并返回结果。此选项是副本集的辅助成员上out的唯一可用选项。

out: { inline: 1 }

结果必须符合BSON 文档的最大尺寸

Required Access

如果您的 MongoDB 部署强制执行身份验证,则执行mapReduce命令的用户必须拥有以下特权操作:

使用{out : inline}输出选项进行 Map-reduce:-find

输出到集合时使用replace动作进行 Map-reduce:-find,-insert,-replace

输出到集合时使用mergereduce动作进行 Map-reduce:-find,-insert,-update

readWrite内置角色提供执行 Map 减少聚合的必要权限。

Map-Reduce Examples

mongo shell 中,db.collection.mapReduce()方法是mapReduce命令的包装。以下示例使用db.collection.mapReduce()方法:

请考虑对包含以下原型文档的集合orders进行以下 map-reduce 操作:

{
     _id: ObjectId("50a8240b927d5d8b5891743c"),
     cust_id: "abc123",
     ord_date: new Date("Oct 04, 2012"),
     status: 'A',
     price: 25,
     items: [ { sku: "mmm", qty: 5, price: 2.5 },
              { sku: "nnn", qty: 5, price: 2.5 } ]
}

返回每个 Client 的总价

orders集合执行 map-reduce 操作以对cust_id进行分组,并为每个cust_id计算price的总和:

var mapFunction1 = function() {
                       emit(this.cust_id, this.price);
                   };
var reduceFunction1 = function(keyCustId, valuesPrices) {
                          return Array.sum(valuesPrices);
                      };
db.orders.mapReduce(
                     mapFunction1,
                     reduceFunction1,
                     { out: "map_reduce_example" }
                   )

此操作将结果输出到名为map_reduce_example的集合。如果map_reduce_example集合已经存在,则该操作将使用此 map-reduce 操作的结果替换内容:

计算订单和总数量以及每件商品的平均数量

在此示例中,您将对orders集合上所有ord_date值大于01/01/2012的文档执行 map-reduce 操作。工序按item.sku字段分组,并计算每个sku的订单数量和总 Order 量。通过计算每个sku值的每个订单的平均数量来结束该操作:

var mapFunction2 = function() {
                       for (var idx = 0; idx < this.items.length; idx++) {
                           var key = this.items[idx].sku;
                           var value = {
                                         count: 1,
                                         qty: this.items[idx].qty
                                       };
                           emit(key, value);
                       }
                    };
var reduceFunction2 = function(keySKU, countObjVals) {
                     reducedVal = { count: 0, qty: 0 };

                     for (var idx = 0; idx < countObjVals.length; idx++) {
                         reducedVal.count += countObjVals[idx].count;
                         reducedVal.qty += countObjVals[idx].qty;
                     }

                     return reducedVal;
                  };
var finalizeFunction2 = function (key, reducedVal) {

                       reducedVal.avg = reducedVal.qty/reducedVal.count;

                       return reducedVal;

                    };
db.orders.mapReduce( mapFunction2,
                     reduceFunction2,
                     {
                       out: { merge: "map_reduce_example" },
                       query: { ord_date:
                                  { $gt: new Date('01/01/2012') }
                              },
                       finalize: finalizeFunction2
                     }
                   )

此操作使用query字段仅选择ord_date大于new Date(01/01/2012)的那些文档。然后将结果输出到集合map_reduce_example。如果map_reduce_example集合已经存在,则该操作会将现有内容与该 map-reduce 操作的结果合并。

有关更多信息和示例,请参见Map-Reduce页和执行增量 Map-减少

Output

mapReduce命令增加了对bypassDocumentValidation选项的支持,该选项使您可以在使用验证规则在集合中插入或更新文档时绕过document validation

如果设置out参数以将结果写入集合,则mapReduce命令以以下形式返回文档:

{
    "result" : <string or document>,
    "timeMillis" : <int>,
    "counts" : {
        "input" : <int>,
        "emit" : <int>,
        "reduce" : <int>,
        "output" : <int>
    },
    "ok" : <int>,
}

如果设置out参数以内联方式输出结果,则mapReduce命令以以下形式返回文档:

{
    "results" : [
       {
          "_id" : <key>,
          "value" :<reduced or finalizedValue for key>
       },
       ...
    ],
    "timeMillis" : <int>,
    "counts" : {
       "input" : <int>,
       "emit" : <int>,
       "reduce" : <int>,
       "output" : <int>
    },
    "ok" : <int>
}

Additional Information

首页