Aggregate的使用,有利于我们对MongoDB中的集合进行进一步的拆分。
示例:
1 2 3 4 5
| db.collection.aggregate( {$match:{x:1}, {limit:10}, {$group:{_id:"$age"}}} );
|
操作符介绍:
$project:包含、排除、重命名和显示字段
$match:查询,需要同find()一样的参数
$limit:限制结果数量
$skip:忽略结果的数量
$sort:按照给定的字段排序结果
$group:按照给定表达式组合结果
$unwind:分割嵌入数组到自己顶层文件
============================================================
这是MongoDB官网上的一个Data Model:
1 2 3 4 5 6 7 8 9 10
| { "_id": "10280",//zipcode "city": "NEW YORK",//城市 "state": "NY",//城市缩写 "pop": 5574,//人口 "loc": [ //经纬度 -74.016323, 40.710537 ] }
|
1、查出一个超过1千万人口的城市
1 2 3 4
| db.zipcodes.aggregate( {$group:{_id:"$state", totalPop:{$sum:"$pop"}}, {$match:{totalPop:{$gte: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
1 2 3 4 5 6
| db.zipcodes.aggregate( { $group : { _id : { state : "$state", city : "$city" }, pop : { $sum : "$pop" } } }, { $group : { _id : "$_id.state", avgCityPop : { $avg : "$pop" } } } )
|
上述示例中出现了两个$group,那是什么含义呢?
第一个$group是将原来的zipcodes 这个 document变成新的,如:
1 2 3 4 5 6 7
| { "_id" : { "state" : "CO", "city" : "EDGEWATER" }, "pop" : 13154 }
|
第二个 $group是在,原有的基础之上,再进行一次重新格式化数据,再生成新的document,如:
1 2 3 4
| { "_id" : "MN", "avgCityPop" : 5335 },
|
3、查询每个州人口最大和最小的城市
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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"} } } );
|
数据结构,如下:
1 2 3 4 5 6 7 8 9 10 11
| { "state" : "RI", "biggestCity" : { "name" : "CRANSTON", "pop" : 176404 }, "smallestCity" : { "name" : "CLAYVILLE", "pop" : 45 } }
|