聚合管道是链式调用,上面的处理结果会用作下次处理初始值
1.$match
可以看做筛选,就是查找符合条件的数据
// 查找user_id=user_id的数据
{
$match: { user_id: ObjectId(user_id) }
}
// 查找array里包含的user_id的数据
{
$match: { user_id: { $in: array } }
}
2. $skip和 $limit
这两个是做翻页用的
// page->第几页 size->每页多少个
[
{ $skip: (Number(page) - 1) * Number(size) },
{ $limit: Number(size) }
]
3.$lookup
表与表关联查询
如:我在a表存了b表的id,也就是a里有一个 b_id 字段
a表
{
_id: "....",
b_id: "aaaaa",
name: "这是a"
......
}
b表
{
_id: "aaaaa",
name: "这是b"
}
a.aggregate([
{
$lookup: {
from: 'bs',// 要查询的表(带s是因为mongodb表自动加s,这里的名字必须是真正的表名)
localField: 'b_id',// 根据什么字段,这里是a里的b_id
foreignField: '_id',// 要匹配的字段,找b里面_id=b_id的数据
as: 'b_data'// 放入的字段
}
}
])
结果
{
_id: "....",
b_id: "aaaaa",
name: "这是a",
b_data: {
_id: "aaaaa",
name: "这是b"
}
......
}
4.$sort
排序
// 根据创建时间倒序
{
$sort: { created_at: -1 }
}
5.$unwind
将一个数组字段拆分成多个
值
{
name: "parent",
children: [
{
name: "child1"
},
{
name: "child2"
}
]
}
{
$unwind: "$children"
}
结果
[
{
name: "parent",
children: {
name: "child1"
}
},
{
name: "parent",
children: {
name: "child2"
}
}
]
6.$project
控制值得显示,重命名,还有加减乘除等操作(着实有点多,脑壳疼)
模拟数据
{
"state": -1,
"sort": 1,
"is_delete": 0,
"_id": "5f4907f1984fd26e900ec8e8",
"name": "总经理",
"created_at": "2020-08-28T13:34:41.282Z",
"update_at": "2020-08-28T13:34:41.282Z",
"__v": 0
}
// 只显示sort和name。(0是不显示,1是显示,_id不写默认显示)
aggregate([
{ $project : { _id: 0, sort : 1 , name : 1 }}
])
// 把name换成positionName显示
aggregate([
{ $project : { _id: 0, sort : 1 , positionName : "$name" }}
])
// sort输出的值乘2
// 加法($add)、减法($subtract)、乘法($multipy)、除法($divide)
aggregate([
{ $project : { _id: 0, sort : { "$multipy": [ "$sort",2 ] } , positionName : "$name" }}
])
// 还可以进行逻辑输出,关系运算,逻辑运算,字符操作等(如将两个字符连接成一个)
7.$group
给数据分组计算
模拟数据
{ "item" : "aaa", "price" : 10, "quantity" : 2, "date" : ISODate("2014-03-01T08:00:00Z") },
{ "item" : "bbb", "price" : 20, "quantity" : 1, "date" : ISODate("2014-03-01T09:00:00Z") },
{ "item" : "ccc", "price" : 5, "quantity" : 10, "date" : ISODate("2014-03-15T09:00:00Z") },
{ "item" : "ccc", "price" : 5, "quantity" : 20, "date" : ISODate("2014-04-04T11:21:39.736Z") },
{ "item" : "aaa", "price" : 10, "quantity" : 10, "date" : ISODate("2014-04-04T21:23:13.331Z") }
根据item进行分类,并且统计数量放入count
[
{
$group : {
_id : "$item",// 要进行合并的字段,前面的_id是必须的可以为空(不能改真的恶心)
count: { $sum : 1}
}
}
]
结果
[
{_id:aaa:count:2},
{_id:bbb:count:1},
{_id:ccc:count:2}
]
求price的和 与 quantity平均数
{
$group : {
_id : "$item",
total: { $sum : "$price"},
avg: { $avg: "$quantity" }
}
}
更多的运算
$max 最大值
$min 最小值
$first 第一个值
$last 最后一个值
按月,日和年对文档进行分组
{
$group : {
_id : { month: { $month: "$date" }, day: { $dayOfMonth: "$date" }, year: { $year: "$date" } },
// [ "$price", "$quantity" ] 指的是操作这两个数据,$multiply 对多个字段进行求和操作
totalPrice: { $sum: { $multiply: [ "$price", "$quantity" ] } }
}
}
将属于同一个item的price放入prices数组(会重复)
{ $group : { _id : "$item", prices: { $push: "$price" } } }
下面是不会重复写法
{ $group : { _id : "$item", prices: { $addToSet: "$price" } } }
通过item分类将整条数据放入数组
{ $group : { _id : "$item", arr: { $push: "$$ROOT" } } }
8.$facet
可以理解为创建多个管道
{ $facet:
{
<outputField1>: [ <stage1>, <stage2>, ... ],
<outputField2>: [ <stage1>, <stage2>, ... ],
...
}
}