MongoDB 聚合

聚合操作对查询到的记录分组,然后对每组记录进行统计计算,返回统计结果。在SQL中,count(*)配合group by可以统计每组记录的条数,就相当于MongoDB中的聚合sum。

aggregate() 方法

MongoDB中,聚合操作可以使用aggregate()方法。

语法

aggregate()方法的基本语法如下:

db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

例子

在qikegu集合中有以下数据:

> db.qikegu.find().pretty()
{
        "_id" : ObjectId("5cf7b91d9ad87fde6fd23a06"),
        "title" : "MongoDB 概述",
        "description" : "MongoDB是一个以文档为中心的NOSQL数据库",
        "by" : "qikegu.com",
        "url" : "https://www.qikegu.com",
        "tags" : [
                "mongodb",
                "database",
                "NoSQL"
        ],
        "likes" : 88
}
{
        "_id" : ObjectId("5cf7b91d9ad87fde6fd23a07"),
        "title" : "MongoDB 优势",
        "description" : "MongoDB相对于RDBMS的优势",
        "by" : "qikegu.com",
        "url" : "https://www.qikegu.com",
        "tags" : [
                "mongodb",
                "database",
                "NoSQL"
        ],
        "likes" : 89,
        "comments" : [
                {
                        "user" : "user1",
                        "message" : "My first comment",
                        "dateCreated" : ISODate("2018-12-09T18:35:00Z"),
                        "like" : 0
                }
        ]
}

现在,要统计qikegu.com写了多少个教程,可以使用aggregate()方法:

> db.qikegu.aggregate([{$group : {_id : "$by", num_tutorial : {$sum : 1}}}])
{ "_id" : "qikegu.com", "num_tutorial" : 2 }

上面的例子,等价的SQL查询是

select `by`, count(*) from qikegu group by `by`

在上面的例子中,按照字段by对结果进行分组,并统计分组中记录条数。下面是聚合表达式的列表:

表达式 描述 例子
$sum 汇总集合中文档的字段值。 db.qikegu.aggregate([{group : {_id : “by”, num_tutorial : {sum : “likes”}}}])
$avg 计算集合中,所有文档中所有给定值的平均值。 db.qikegu.aggregate([{group : {_id : “by”, num_tutorial : {avg : “likes”}}}])
$min 获取集合中,文档字段的最小值 db.qikegu.aggregate([{group : {_id : “by”, num_tutorial : {min : “likes”}}}])
$max 获取集合中,文档字段的最大值 db.qikegu.aggregate([{group : {_id : “by”, num_tutorial : {max : “likes”}}}])
$push 将全部文档的某个字段值作为数组插入到结果中。 db.qikegu.aggregate([{group : {_id : “by”, url : {push: “url”}}}])
$addToSet 将全部文档的某个字段值作为数组插入到结果中,但字段值不重复。 db.qikegu.aggregate([{group : {_id : “by”, url : {addToSet : “url”}}}])
$first 获取分组中的最后一个文档,通常,文档是有序的这个操作才有意义。 db.qikegu.aggregate([{group : {_id : “by”, first_url : {first : “url”}}}])
$last 获取分组中的首个文档,通常,文档是有序的这个操作才有意义。 db.qikegu.aggregate([{group : {_id : “by”, last_url : {last : “url”}}}])

管道

在UNIX命令中,管道可以让某些命令的输出,作为另一个命令的输入,以此类推。MongoDB的聚合框架中也支持相同的概念,某些操作阶段输出一组文档,这些文档可以作为另一组操作阶段的输入,以此类推。

下面是聚合框架的可能阶段,可以把这些阶段串联组合起来:

  • $project — 用于从集合中选择某些字段。
  • $match — 这是一个过滤操作,过滤文档。
  • $group — 这是如上所述的实际聚合。
  • $sort — 对文档进行排序。
  • $skip – 结果偏移量,类似mysql中的offset。
  • $limit — 限定结果数量。
  • $unwind – 用于展开使用数组的文档。例如:
    { "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] }
    

    会被展开成为:

    { "_id" : 1, "item" : "ABC1", "sizes" : "S" }
    { "_id" : 1, "item" : "ABC1", "sizes" : "M" }
    { "_id" : 1, "item" : "ABC1", "sizes" : "L" }
    


浙ICP备17015664号 浙公网安备 33011002012336号 联系我们 网站地图  
@2019 qikegu.com 版权所有,禁止转载