【MongoDB】Aggregation Pipeline——聚合管道
2017-11-09 20:36
381 查看
MongoDB提供聚合管道技术进行处理输入的数据,数据经过一个一个的stage,每个stage将数据处理后的结果传递给下一个stage,最终得到多重处理后的结果。
Aggregate提供了多种stage可供选择,match、sort、limit、limit等。对于嵌套数据的处理可以在Aggregate中实现,减少在代码上的编写。
2.geoNear必须是管道的第一个stage3.match、limit、skip 尽可能早的使用
上述情况都是在紧邻着出现时,才会做优化处理。
当队列中出现多个limit、skip时,等价于后面的stage。
1.4 惰性执行
聚合管道在对数据处理时,采用惰性执行,它不会扫描所有的字段(包含嵌套字段),只有使用到的字段才会进行扫描。
注意:$_id指向原文档的_id字段。1,表示保留原文档的字段
可接受返回值
常与表达式$cond一起使用
$geoNear
二维地理信息
在处理嵌套文档时提供很大遍历;
提供两个集合之间联合查询的接口。
Aggregate提供了多种stage可供选择,match、sort、limit、limit等。对于嵌套数据的处理可以在Aggregate中实现,减少在代码上的编写。
一、优化策略
1.1手动优化
1.match、sort 可以使用索引2.geoNear必须是管道的第一个stage3.match、limit、skip 尽可能早的使用
1.2 自动优化阶段
Aggregate在执行聚合操作之前会有一个自动优化阶段,它会在小范围内优化stage队列。[{$sort:{}},{$match:{}}] --> [{$match:{}},{$sort:{}}] [{$skip:n},{$limit:m}] --> [{$limit:m},{$skip:n}] [{$project:{}},{$limit:m},{$skip:n}] --> [{$limit:m},{$skip:n},{$project:{}}] 对于skip和limit测试时,发现不同顺序时,结果不一致。似乎优化并没有成功
上述情况都是在紧邻着出现时,才会做优化处理。
1.3 重复的stage处理
[{$limit:100},{$limit:10}] --> [{$limit:10}] [{$skip:5},{$skip:2}] --> [{$skip:7}]
当队列中出现多个limit、skip时,等价于后面的stage。
1.4 惰性执行
聚合管道在对数据处理时,采用惰性执行,它不会扫描所有的字段(包含嵌套字段),只有使用到的字段才会进行扫描。
二 Stages
MongoDB的聚合管道是由stage组成的,当文档通过管道时每一个stage都对文档进行处理。对于输入的文档,stage可以产生新的文档或者过滤文档,但是stage不需要为它产生一个输出文档。管道中可以使用多个stage。原文链接:https://docs.mongodb.com/manual/core/aggregation-pipeline/2.1 stages
原文链接:https://docs.mongodb.com/manual/reference/operator/aggregation/#aggregation-pipeline-operator-reference$match
过滤文档,将匹配成功地文档传递给下一个stage。demo: Db.data.aggregaet([ {$macth:{‘_id’:1}} ])
$project
拆分重组JSONP对象,保留需要的字段demo Db.data.aggregate([ {$project:{_id:’$_id’,name:1,age:’$age’}} ])
注意:$_id指向原文档的_id字段。1,表示保留原文档的字段
$group
分组查询。参照元素即输出元素,_id中可以设置分组的依据,其余自定义字段必须是可累加的字段(sum,push)demo db.data.aggregate([{$group:{_id:{name:"$name"},num:{$sum:1},money:{$sum:1.5}]) { "_id" : { "name" : "apple" }, "num" : 3, "money" : 4.5 }
$redact
编辑文档,对嵌套文档选择性编辑可接受返回值
> $$DESCEND 可以编辑当前文档中的嵌套文档 > $$PRUNE 不可以编辑当前文档及其包含的嵌套文档 > $$KEEP 保持当前文档状态
常与表达式$cond一起使用
db.data.aggregate([ {$match:{title:'123 Department Report'}}, {$redact:{ $cond:{ if:{ $gt:[{$size:['$tags']},1] }, then:'$$DESCEND', else:'$$PRUNE' } }} ])
$unwind
展开数组,将一条带有内嵌的数组的数据展开成多条数据。$sample
随机选择N条数据$geoNear
二维地理信息
$lookup
联合查询,类似与关系数据库的左查询{$lookup:{ from:”collection name”, localField:”local field name”, foreignField:”foreign field name”, as:”output field” //输出是一个数组 }}
$out
将聚合结果输入到一个新的集合(若集合已经存在,会覆盖集合中原有数据)$out:’out colloection name’
$indexStats
查看索引的信息,每个集合都有一个默认的索引db.data.aggregate( [ { $indexStats: { } } ] )
$bucket
统计连续区间的数据的数量,左闭右开db.summary.aggregate([{ $bucket:{ groupBy:'$time', boundaries:['2017-10','2017-11'], default:'other', output:{ "count": { $sum: 1 }, 'datas':{$push:'$data'} } } }])
$facet
在它里面可以使用多个stage,输出是一个对象,对象中的每个字段都是一个数组。db.summary.aggregate([{ $facet:{ datas:[ {$unwind:'$data'} ], time:[ {$group:{_id:{time:'$time'}}} ] } }])
$sortByCount
倒序输出,等价于group和sort的组合使用$addFields
增加多个字段db.summary.aggregate([ { $addFields:{ size:{$size:'$data'} } } ])
$replaceRoot
替换对象到根路径,必须是对象{}db.summary.aggregate([ {$unwind:'$data'}, {$replaceRoot:{newRoot:'$data'}} ])
总结:
聚合管道在处理嵌套数据时,可以对一个文档进行多重处理。输入数据为一条,多次处理,每次处理后将结果直接传递给下一个stage,最终得到一个输出结果;在处理嵌套文档时提供很大遍历;
提供两个集合之间联合查询的接口。
相关文章推荐
- MongoDB小结28 - 聚合管道【$match】
- MongoDB:6-MongoDB的聚合和管道
- MongoDB小结29 - 聚合管道【$cond】
- MongoDB 聚合管道(一)(Aggregation Pipeline)
- MongoDB(6)数据聚合 & 管道操作
- MongoDB 聚合管道(Aggregation Pipeline)
- Mongodb中数据聚合之聚合管道aggregate
- Mongodb 聚合管道(Aggregation Pipeline)
- MongoDB 聚合(管道与表达式)
- MongoDB 聚合管道(Aggregation Pipeline)
- MongoDB 聚合管道(Aggregation Pipeline)
- MongoDB 聚合管道(二)(Aggregation Pipeline)
- MongoDB 聚合管道(Aggregation Pipeline)
- Mongodb 聚合管道
- Mongodb中数据聚合之聚合管道aggregate
- MongoDB小结27 - 聚合管道【$project】
- MongoDB 聚合管道(Aggregation Pipeline)
- MongoDB聚合管道
- MongoDB 聚合管道(Aggregation Pipeline)
- mongodb之聚合管道操作符的错误用法之$project(一)