您的位置:首页 > 数据库 > Mongodb

MongoDB Aggregation, mongoDB的聚合操作

2016-12-05 14:20 519 查看
一直认为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:
a string for the collection name if out did
not specify the database name, or
a document with both db and collection fields
if out specified both a database and collection name.
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: