MongoDB的聚合函数 Aggregate

Aggregate的使用,有利于我们对MongoDB中的集合进行进一步的拆分。

示例:

db.collection.aggregate(  
    {$match:{x:1},  
    {limit:10},  
    {$group:{_id:"$age"}}}  
);
操作符 介绍
$project: 包含、排除、重命名和显示字段
$match: 查询,需要同find()一样的参数
$limit: 限制结果数量
$skip: 忽略结果的数量
$sort: 按照给定的字段排序结果
$group: 按照给定表达式组合结果
$unwind: 分割嵌入数组到自己顶层文件
表达式描述实例
$sum 总结从集合中的所有文件所定义的值. db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
$avg 从所有文档集合中所有给定值计算的平均. db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
$min 获取集合中的所有文件中的相应值最小. db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
$max 获取集合中的所有文件中的相应值的最大. db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
$push 值插入到一个数组生成文档中. db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSet 值插入到一个数组中所得到的文档,但不会创建重复. db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
$first 根据分组从源文档中获取的第一个文档。通常情况下,这才有意义,连同以前的一些应用 “$sort”-stage. db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$last 根据分组从源文档中获取最后的文档。通常,这才有意义,连同以前的一些应用 “$sort”-stage. db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])

这是MongoDB官网上的一个Data Model:

{  
  "_id": "10280",//zipcode  
  "city": "NEW YORK",//城市  
  "state": "NY",//城市缩写  
  "pop": 5574,//人口  
  "loc": [ //经纬度  
    -74.016323,  
    40.710537  
  ]  
}

1、查出一个超过1千万人口的城市

db.zipcodes.aggregate(  
    {$group:{_id:"$state", totalPop:{$sum:"$pop"}},  
    {$match:{totalPop:{$get:10000000}}}  
);

上面的语句相当于: SELECT state, sum(pop) totalPop from zipcodes group by state having by totalPop >= 10000000;

分析:

$group主要是用于分组,其中_id是用组的类型集合,totalPop是生成的一个新的字段,用于存储总数。

其实,document经过$group之后,系统会为其生成一个新的document(新的documment为{"_id":"AK","totalPop":550043}),这在下面的例子中,我们会看得更清楚。

$match,相当于为新生成的document提供查询功能

2、求平均人口,每个state

db.zipcodes.aggregate( { $group :  
                         { _id : { state : "$state", city : "$city" },  
                           pop : { $sum : "$pop" } } },  
                       { $group :  
                       { _id : "$_id.state",  
                         avgCityPop : { $avg : "$pop" } } } )

上述示例中出现了两个$group,那是什么含义呢?

第一个$group是将原来的zipcodes 这个 document变成新的,如:

{  
  "_id" : {  
    "state" : "CO",  
    "city" : "EDGEWATER"  
  },  
  "pop" : 13154  
}

第二个 $group是在,原有的基础之上,再进行一次重新格式化数据,再生成新的document,如:

{  
  "_id" : "MN",  
  "avgCityPop" : 5335  
},

3、查询每个州人口最大和最小的城市

db.zipcodes.aggregate(  
    {$group:{_id:{state:"$state",city:"$city"}, totalPop:{$sum:"$pop"}}},//统计州的所有人,生成一个新的文档,是关于州与其总人口  
    {$sort:{"totalPop":-1}},//对新文档,根据人口数倒序排序  
    {$group:{_id:"$_id.state",  
        "biggestCity":{$first:"$_id.city"},//最大人口的城市  
        "biggestPop":{$first:"totalPop"},//最大人口的数量  
        "smallestCity":{$last:"$_id.city"},  
        "smallestPop":{$last:"totalPop"}  
    }},//重新组成一个新的文件,包含,州名,最大人口数和最小人口数  
    //本来结构到此基本上差不多了  
    //但我们需要再对数据进行格式化  
    {$project:  
        {_id:0,  
        state:"$_id",  
        biggestCity:{name:"$biggestCity",pop:"$biggestPop"},  
        smallestCity:{name:"$smallestCity",pop:"$smallestPop"}        
        }  
    }  
);

数据结构,如下:

{  
  "state" : "RI",  
  "biggestCity" : {  
    "name" : "CRANSTON",  
    "pop" : 176404  
  },  
  "smallestCity" : {  
    "name" : "CLAYVILLE",  
    "pop" : 45  
  }  
}

results matching ""

    No results matching ""