一直认为mongoDB中的Aggregation就是聚合管道,今天看了官网的介绍才有了更多的了解。
聚合的作用:将多条记录放在一起,然后通过多种操作获取单一的结果。网上有很多描述,可以参考。
聚合方法:MongoDB提供了聚合管道,map-reduce function, single purpose aggregation methods 三种聚合方式。
聚合管道有很多介绍,不在赘述。
map-reduce function:
count,group等能做的事情,MapReduce都能做。它可以轻松并行化到多个服务器,它会拆分问题,再将各个部分发送到不同的机器上,让每台机器都完成一部分。当所有机器都完成的时候,再把结果汇集起来形成最终的完整结果。
MapReduce的步骤:1.映射,将操作映射到集合中的每个文档,这个操作要么"无作为",要么“产生一些键和X个值”。然后就是中间环节,称作洗牌(shuffle),按照键进行分组,并将产生的键值组成列表放到对应的键中。化简(reduce),则把列表中的值化简成一个简单的值。这个值被返回,然后接着洗牌。直到每个键的列表只有一个值为止。这个值也就是最后结果。
使用MapReduce的代价是速度:group不是很快,MapReduce更慢,绝对不要用在"实时"环境中。要作为后台任务来运行MapReduce,将创建一个保存结果的集合,可以对这个集合进行实时查询。
MongoDB提供了很多命令用于对collection进行聚合操作,当然也可以用于子集合。
db.runCommand( { mapReduce: <collection>,-- collection的名称,collection在被map function 处理之前会使用query 等过滤。 map: <function>,----JavaScript函数,或者通过key 映射一个值,或者使用key 和value一对值emit. 见注释1. reduce: <function>,----javaScript函数,将所有值简化成一个键值对应的对象,使用方法见注释2. finalize: <function>,----将结果通过key ,value的形式返回。 out: <output>,----注释三 query: <document>, sort: <document>, limit: <number>, scope: <document>, jsMode: <boolean>, verbose: <boolean>, bypassDocumentValidation: <boolean>, collation: <document> } )注释一: map函数用来将每个document转换成0或者多个documents,根据定义的作用域参数获取变量。 Map函数调用emit(key,value)遍历集合中所有的记录.将key与value传给Reduce函数进行处理。
函数写法1:获取作用域参数中的结果
function() {
... emit(key, value); }* 文档代表的是当前文档
* 任何情况下都不要试图获取database
* 函数不能再使用另一个外部函数
*一个单独的emit最多只能占用BSON document Size的一半大小,3.4版本是16M,因此不能超过8M。
函数方法二:
下面的map 将在document的status 键值符合要求时,调用emit函数一次或者0次。
function() { if (this.status == 'A') emit(this.cust_id, 1); }下面的map将根据document的item 键值的数目,多次调用emit。
function() { this.items.forEach(function(item){ emit(item.sku, 1); }); }注释二:
函数格式:
function(key, values) { ... return result; }
* reduce 函数不可以获取database
* 不能影响外部系统
* 当键值只有一个值的时候,不会调用reduce函数。必须是数组。
* 可以为同一个键值多次调用该函数
* 该函数可以访问作用域中定义的所有变量
* reduce的内容必须小于BSON max SIZE的一半,即小于8M(3.4版本)。
注释三:
* 结果存储在一个新的collection
out: <collectionName>
* 当使用一个已经存在的collection,It is not available on secondary members of replica sets.
out: { <action>: <collectionName> [, db: <dbName>] [, sharded: <boolean> ] [, nonAtomic: <boolean> ] }其中action可以使用下面的其中一个:
replace: 覆盖原来的内容
merge: 将输出的内容和原有的内容合并,如果有相同的key值,则内容覆盖。
reduce: 将输出的内容和原有的内容合并,如果有相同的key值,使用reduce function 将新的document和旧document进行计算,保存计算结果。
db---
可选,数据库名称,默认使用和待处理的collection相同的数据库。
sharded----分片
可选,如果为true,并且数据库的分片是打开的,则输出将使用_id作为shard key进行分片操作。
nonAtomic---非原子
可选,仅在merge和reduce action中可以使用,默认值为false.
当为false时, map reduce 操作期间会锁定数据库。
当为true是,map reduce操作期间其他客户端可以读取output collection.
* Output Inline---map reduce操作在内容中进行,并返回结果。 This option is the only available option forout on secondary members of replica sets.
out: { inline: 1 }
范围结果大小不得超过BSON max Size 16M.
Map-Reduce举例:
db.collection.mapReduce() 集合了mapReduce的命令,
假如collection 中存的记录如下:
{ _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 } ] }
例子可参考官网: https://docs.mongodb.com/manual/reference/command/mapReduce/#mapreduce-reduce-cmd
Output
The mapReduce command adds support for the bypassDocumentValidation option, which lets you bypass document validation when inserting or updating documents in a collection with validation rules.
If you set the out parameter to write the results to a collection, the mapReduce command returns a document in the following form:
{
"result" : <string or document>,
"timeMillis" : <int>,
"counts" : {
"input" : <int>,
"emit" : <int>,
"reduce" : <int>,
"output" : <int>
},
"ok" : <int>,
}
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>
},
...
],
"timeMillis" : <int>,
"counts" : {
"input" : <int>,
"emit" : <int>,
"reduce" : <int>,
"output" : <int>
},
"ok" : <int>
}
-
mapReduce.
result
-
For output sent to a collection, this value is either:
-
mapReduce.
results
-
For output written inline, an array of resulting documents. Each resulting document contains two fields:
- _id field contains the key value,
- value field contains the reduced or finalized value for the associated key.
-
mapReduce.
timeMillis
-
The command execution time in milliseconds.
-
mapReduce.
counts
-
Various count statistics from the mapReduce command.
-
mapReduce.counts.
input
-
The number of documents the mapReduce command called the map function.
-
mapReduce.counts.
emit
-
The number of times the mapReduce command called the emit function.
-
mapReduce.counts.
reduce
-
The number of times the mapReduce command called the reduce function.
-
mapReduce.counts.
output
-
The number of output values produced.
-
mapReduce.
ok
-
A value of 1 indicates the mapReduce command ran successfully. A value of 0 indicates an error.
MapReduce的操作理解也可以参考:http://blog.csdn.net/sithlqf/article/details/4523886