使用邮政编码数据集进行汇总
在本页面
本文档中的示例使用zipcodes
集合。该收藏集位于:media.mongodb.org/zips.json。使用mongoimport将数据集加载到mongod实例中。
Data Model
zipcodes
集合中的每个文档都具有以下格式:
{
"_id": "10280",
"city": "NEW YORK",
"state": "NY",
"pop": 5574,
"loc": [
-74.016323,
40.710537
]
}
-
_id
字段将邮政编码保存为字符串。 -
city
字段包含城市名称。一个城市可以具有多个与之相关联的邮政编码,因为该城市的不同部分可以分别具有不同的邮政编码。 -
state
字段包含两个字母的状态缩写。 -
pop
字段用于保存人口。 -
loc
字段将位置保存为经度纬度对。
aggregate() Method
以下所有示例都在mongo shell 中使用aggregate()帮助器。
aggregate()方法使用aggregation pipeline将文档处理为汇总结果。 aggregation pipeline由stages组成,每个阶段处理文档沿管道传递时。文档按 Sequences 通过各个阶段。
mongoShell 程序中的aggregate()方法为aggregate数据库命令提供了包装。有关数据聚合操作的更多惯用界面,请参见driver的文档。
人口超过 1000 万的回返国
以下汇总操作将返回总人口超过 1000 万的所有 State:
db.zipcodes.aggregate( [
{ $group: { _id: "$state", totalPop: { $sum: "$pop" } } },
{ $match: { totalPop: { $gte: 10*1000*1000 } } }
] )
在此示例中,aggregation pipeline由$group阶段和随后的$match阶段组成:
- $group阶段按
state
字段对zipcode
集合的文档进行分组,为每个状态计算totalPop
字段,并为每个唯一状态输出文档。
新的按状态的文档有两个字段:_id
字段和totalPop
字段。 _id
字段包含state
的值;即按字段分组。 totalPop
字段是一个计算的字段,其中包含每个 State 的总人口。要计算值,$group使用$sum运算符为每个 State 添加人口字段(pop
)。
在$group阶段之后,管道中的文档类似于以下内容:
{
"_id" : "AK",
"totalPop" : 550043
}
此聚合操作的等效SQL为:
SELECT state, SUM(pop) AS totalPop
FROM zipcodes
GROUP BY state
HAVING totalPop >= (10*1000*1000)
各 State 的平均城市人口
以下汇总操作返回每个 State 的城市平均人口:
db.zipcodes.aggregate( [
{ $group: { _id: { state: "$state", city: "$city" }, pop: { $sum: "$pop" } } },
{ $group: { _id: "$_id.state", avgCityPop: { $avg: "$pop" } } }
] )
在此示例中,aggregation pipeline由$group阶段组成,随后是另一个$group阶段:
在管道中的此阶段之后,文档类似于以下内容:
{
"_id" : {
"state" : "CO",
"city" : "EDGEWATER"
},
"pop" : 13154
}
- 第二个$group阶段按
_id.state
字段(即_id
文档内的state
字段)对管道中的文档进行分组,使用$avg表达式计算每个 State 的平均城市人口(avgCityPop
),并输出每个 State 的文档。
此聚合操作产生的文档类似于以下内容:
{
"_id" : "MN",
"avgCityPop" : 5335
}
按 State 归还最大和最小的城市
以下汇总操作返回每个 State 人口最小和最大的城市:
db.zipcodes.aggregate( [
{ $group:
{
_id: { state: "$state", city: "$city" },
pop: { $sum: "$pop" }
}
},
{ $sort: { pop: 1 } },
{ $group:
{
_id : "$_id.state",
biggestCity: { $last: "$_id.city" },
biggestPop: { $last: "$pop" },
smallestCity: { $first: "$_id.city" },
smallestPop: { $first: "$pop" }
}
},
// the following $project is optional, and
// modifies the output format.
{ $project:
{ _id: 0,
state: "$_id",
biggestCity: { name: "$biggestCity", pop: "$biggestPop" },
smallestCity: { name: "$smallestCity", pop: "$smallestPop" }
}
}
] )
在此示例中,aggregation pipeline由$group阶段,$sort
阶段,另一个$group阶段和$project
阶段组成:
在管道的此阶段,文档类似于以下内容:
{
"_id" : {
"state" : "CO",
"city" : "EDGEWATER"
},
"pop" : 13154
}
-
$sort阶段按
pop
字段值(从最小到最大)对管道中的文档进行排序;即通过增加 Sequences。此操作不会更改文档。 -
下一个$group阶段按
_id.state
字段(即_id
文档内的state
字段)对现在分类的文档进行分组,并为每个状态输出一个文档。
该阶段还将为每个状态计算以下四个字段。使用$last表达式,$group运算符将创建biggestCity
和biggestPop
字段,用于存储人口最多的城市和该人口。使用$first表达式,$group运算符创建smallestCity
和smallestPop
字段,该字段存储人口最少的城市和该人口。
在管道的此阶段,这些文档类似于以下内容:
{
"_id" : "WA",
"biggestCity" : "SEATTLE",
"biggestPop" : 520096,
"smallestCity" : "BENGE",
"smallestPop" : 2
}
- 最后的$project阶段将
_id
字段重命名为state
,并将biggestCity
,biggestPop
,smallestCity
和smallestPop
移到biggestCity
和smallestCity
嵌入式文档中。
此聚合操作的输出文档类似于以下内容:
{
"state" : "RI",
"biggestCity" : {
"name" : "CRANSTON",
"pop" : 176404
},
"smallestCity" : {
"name" : "CLAYVILLE",
"pop" : 45
}
}
[1] | 一个城市可以具有多个与之相关联的邮政编码,因为该城市的不同部分可以分别具有不同的邮政编码。 |