MongoDB aggregate 入门
本文可能随着 MongoDB 使用技能的增长而更新,因为 aggregate 可以做的事情太多啦。
在 MongoDB 中,最强大的工具无异于 aggregate,aggregate 接受一个数组,数组的每一项都是管道(pipeline)对象。
管道的概念我们在 Linux 中也遇到过,可以把前面的返回值作为后者的输入值操作。
MongoDB 为我们提供了一系列管道聚集阶段(Pipeline Aggregation Stages):
$project
:增加或删除或重命名(其实就是重新组织)document 的 fields。$match
:根据筛选条件匹配过滤$limit
:限制输出数量$skip
:跳过指定个数的 document$unwind
:解构 document 中的 Array field,变为若干个 item type field 对应的 documents$group
:聚类$sort
:排序$lookup
:相当于 left outer join,在 3.2 版本才加入了这一设定。(在mongoose
中很早就可以使用 populate 来实现 collection 之间的关联,不过和外键概念还是有差别的)
其他的暂时还没用到过,就不多做介绍了。
在下面我们举出一些用到的应用场景:
rename _id
这种用法当然是大材小用,但是可以很方便的说明 $project
的用法:
db.getCollection('releases').aggregate([{ $project: { id: "$_id", _id: 0 }}])
按照时间进行数量统计
在工作中有这样一个需求,我需要根据时间聚类并且 count,在 MongoDB 中的存储结构类似于:
{
"_id" : ObjectId("58f03cfc0cf5e771ec7048f3"),
"data" : [
{
"_id" : ObjectId("58f03d460cf5e771ec7048f4"),
"title" : "你好",
"createdAt" : ISODate("2017-04-14T03:08:54.552Z")
},
{
"version" : "1",
"_id" : ObjectId("58f03d540cf5e771ec7048f5"),
"title" : "你好",
"createdAt" : ISODate("2017-04-14T03:09:08.114Z")
},
{
"_id" : ObjectId("58f03d620cf5e771ec7048f6"),
"title" : "你好",
"createdAt" : ISODate("2017-04-14T03:09:22.567Z")
}
],
"__v" : 0
}
首先我们将 document 中的 array 解构,这样才可以统计,之后根据日期聚类,MongoDB 针对 Date 类型有一系列的处理操作符,之后在使用 $sum
运算符统计即可:
db.getCollection('releases').aggregate([
{ $unwind: "$data" },
{ $group: {
_id: {
date: {
$dateToString: { format: "%Y%m%d", date: "$data.createdAt" }
}
}, count: { $sum: 1 }
}
}
])
如果有筛选的需要,我们可以在中间加上 $match
。如果发现自己写的语句报错了,可以很方便的删除管道中的一个阶段,一阶段一阶段的进行调试。
植入部分
如果您觉得文章不错,可以通过赞助支持我。
如果您不希望打赏,也可以通过关闭广告屏蔽插件的形式帮助网站运作。