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 进阶之——聚合管道的主要内容,如果未能解决你的问题,请参考以下文章

mongo 进阶之—— mongoose 认识

mongo 进阶之—— mongoose 认识

通过 mongo 聚合管道使用 $match 两次

C ++写入mongo,字符串字段在聚合管道中不起作用

管道阶段规范对象必须包含一个带有 php mongo 聚合的字段

管道阶段规范对象必须包含一个带有 php mongo 聚合的字段