mongo 进阶之——聚合管道
Posted twinkle||cll
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mongo 进阶之——聚合管道相关的知识,希望对你有一定的参考价值。
含义
管道是啥?大家都知道,用于承载物体流过的物品,如水管,气体管等连接起来的就是管道。在代码中我们可以理解成链式调用
js 中的管道
let arr = [1,2,3,4,5];
let res =arr.filter(a => a > 1).map(p => ({num: p}))
...
复制代码
上述代码的res的结果是:
[{num: 2},{name: 3}, {name: 4}, {name: 5}]
,上面代码是数组arr经过了filter管道和map管道,最终产出一个结果res
mongo 管道
下面所有的案例都有一个这样的数据集合:
aggregate
语法:db.collection.aggregate(pipeline,options);
1.group得基本用法: 语法: db.test.aggregate([{$group:{_id:'分组得key',test:{操作得事情}}}]);
列如:
- 通过pumber分组,求每组得最小值
db.test.aggregate([{$group:{_id:'$pumber',total:{$min:"$quantity"}}}]);
- 通过pumber分组,求每组的总和
db.test.aggregate([{$group:{_id:'$pumber',total:{$sum:"$quantity"}}]);
- 通过pumber分组,求每组的平均值
db.test.aggregate([{$group:{_id:'$pumber',average:{$avg:'$price'}}}]);
- 通过pumber分组,把每个quantity,放入数组中
db.test.aggregate([{$group:{_id:"$pnumber",quantity:{$push:"$quantity"}}}]);
- 通过pnumber分组,把多个东西放入数组中
db.test.aggregate([{$group:{_id:"$pnumber",suit:{$push:{price:'$price',quantity:'$quantity'}}}}]);
pipeline 类型是Array 语法:db.collection.aggregate( [ { <stage> }, ... ] )
project
$project:
可以对输入文档进行添加新字段或删除现有的字段,可以自定哪些字段显示与不显示。
- 求总条数
db.test.aggregate([{$group:{_id:'$pumber',count:{$sum:1}}},{$project:{"_id":0,"count":1}}])
上面这句话的意思是,先用pumber来进行分组,会有两个字段,一个是"_id"和"count",在后一个管道中用
1
表示显示,0
表示不显示
match
$match
用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作,相当于sql的where.
db.test.aggregate([{$match:{"pumber":'p001'}},{$group:{_id:'$pumber',count:{$sum:'$quantity'}}}]);
相当于sql select sum(quantity) as count from test where pnumber='p001'
limit
$limit
:用来限制MongoDB聚合管道返回的文档数 db.test.aggregate([{$match:{"pumber":'p001'}},{$limit: 1}])
模糊哈希pumber是
p001
,然后限制查询的条数
skip
$skip
:在聚合管道中跳过指定数量的文档,并返回余下的文档。
- 跳两个文件,然后查询限制1条:
db.test.aggregate([{ $skip: 2 },{ $limit: 1 }])
- 限制4条,然后跳过2个文件,得出2个文件
db.test.aggregate([{$limit:4},{$skip:2}]);
注意:
$limit、$skip、$sort、$match
可以使用在阶段管道,如果使用在$group之前可以过滤掉一些数据,提高性能。
unwind
$unwind
:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。 //把查出来的对象数组,然后把数组的值取出来 db.test.aggregate([{$group:{_id:'$pnumber',array:{$push:'$quantity'}}},{$sort:{"pnumber":1}},{$unwind:"$array"}]);
sample
$sample
:使用两种方法之一来获取 N 个随机文档,具体取决于集合的大小,N 的大小以及$sample
在管道中的位置。
如果满足以下所有条件,则$sample
使用伪随机游标选择文档:
$sample
是管道的第一阶段- N 小于集合中文档总数的 5%
- collections 包含 100 多个文档
如果不满足上述任何条件,则$sample
执行收集扫描,然后进行随机排序以选择 N 个文档。在这种情况下,$sample
阶段受排序内存限制
约束。 语法: $sample: { size: <positive integer> }
每一次的结果都是不一样的
sort
$sort
:将输入文档排序后输出。
1是升序,-1是降序
out
$out
:必须为pipeline最后一个阶段管道
,因为是将最后计算结果写入到指定的collection中。如果集合不存在,,会自动创建一个新的集合,存在的话就覆盖. db.test.aggregate([{$group:{_id:"$pumber",sku:{$push:{price:"$price",quantity:"$quantity"}}}},{$out:"skus"}]);
以上是关于mongo 进阶之——聚合管道的主要内容,如果未能解决你的问题,请参考以下文章