文档菜单
文档首页
/
MongoDB 手册
/ /

使用邮编数据集进行聚合

本页内容

  • 数据模型
  • aggregate() 方法
  • 返回人口超过 1000 万的州
  • 返回按州平均城市人口
  • 返回按州最大的和最小的城市

本文件中的示例使用zipcodes 集合。此集合可在media.mongodb.org/zips.json. 使用 mongoimport 将此数据集加载到您的mongod 实例。

zipcodes 集合中的每个文档都具有以下形式

{
"_id": "10280",
"city": "NEW YORK",
"state": "NY",
"pop": 5574,
"loc": [
-74.016323,
40.710537
]
}
  • _id 字段保存为字符串的邮编。

  • city 字段保存城市名称。一个城市可以有多个与之关联的邮编,因为城市的不同部分可以各自有不同的邮编。

  • state 字段保存两个字母的州缩写。

  • pop 字段保存人口。

  • loc 字段保存经纬度对的位置。

以下所有示例都使用了 aggregate() 辅助函数在 mongosh 中。

aggregate() 方法使用 聚合管道 来处理文档并生成聚合结果。一个 聚合管道阶段 组成,每个阶段在管道中处理文档。文档按顺序通过阶段。

aggregate() 方法在 mongosh 中提供了一个数据库命令 aggregate 的包装。有关数据聚合操作更自然的接口,请参阅您 驱动程序 的文档。

以下聚合操作返回所有总人口超过 1000 万的州

db.zipcodes.aggregate( [
{ $group: { _id: "$state", totalPop: { $sum: "$pop" } } },
{ $match: { totalPop: { $gte: 10*1000*1000 } } }
] )

在这个例子中,聚合管道$group 阶段和随后的 $match 阶段组成

  • $group 阶段按 state 字段将 zipcode 集合的文档分组,为每个州计算 totalPop 字段,并为每个唯一的州输出一个文档。

    新的按州文档有两个字段:_id 字段和 totalPop 字段。_id 字段包含 state 的值;即分组字段。totalPop 字段是一个计算字段,包含每个州的总人口。为了计算值,$group 使用 $sum 操作符将每个州的人口字段(pop)相加。

    $group 阶段之后,管道中的文档类似于以下内容

    {
    "_id" : "AK",
    "totalPop" : 550043
    }
  • $match 阶段过滤这些分组文档,仅输出那些 totalPop 值大于或等于 1000 万的文档。$match 阶段不会修改匹配的文档,但输出未修改的匹配文档。

此聚合操作的等效 SQL 为

SELECT state, SUM(pop) AS totalPop
FROM zipcodes
GROUP BY state
HAVING totalPop >= (10*1000*1000)

提示

另请参阅

以下聚合操作返回每个州城市的平均人口

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

在此示例中,聚合管道由 聚合管道 组成,该管道包括 $group 阶段,后跟另一个 $group 阶段

  • 第一个 $group 阶段根据 city 和 state 的组合分组文档,使用 $sum 表达式计算每个组合的人口,并为每个 city 和 state 组合输出一个文档。[1]

    在管道中的此阶段之后,文档类似于以下内容

    {
    "_id" : {
    "state" : "CO",
    "city" : "EDGEWATER"
    },
    "pop" : 13154
    }
  • 第二个 $group 阶段根据 _id.state 字段(即 _id 文档内的 state 字段)对管道中的文档进行分组,使用 $avg 表达式计算每个州的平均城市人口(avgCityPop),并为每个州输出一个文档。

此聚合操作的结果文档类似于以下内容

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

提示

另请参阅

以下聚合操作返回每个州的按人口最大和最小的城市

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" }
}
}
] )

在此示例中,聚合管道由一个 聚合管道 组成,该管道包含一个 $group 阶段、一个 $sort 阶段、另一个 $group 阶段和一个 $project 阶段。

  • 第一个 $group 阶段根据 citystate 的组合对文档进行分组,计算每个组合的 pop 值的总和,并为每个 citystate 组合输出一个文档。

    在此阶段的管道中,文档类似于以下内容

    {
    "_id" : {
    "state" : "CO",
    "city" : "EDGEWATER"
    },
    "pop" : 13154
    }
  • $sort 阶段根据 pop 字段值对管道中的文档进行排序,从小到大;即按升序排序。此操作不会更改文档。

  • 下一个 $group 阶段根据 _id.state 字段(即 _id 文档内的 state 字段)对现在已排序的文档进行分组,并为每个州输出一个文档。

    该阶段还为每个状态计算以下四个字段。使用$last表达式,$group操作符创建了biggestCitybiggestPop字段,用于存储人口最多的城市及其人口。使用$first表达式,$group操作符创建了smallestCitysmallestPop字段,用于存储人口最少的城市及其人口。

    在此阶段的管道中,文档类似于以下内容

    {
    "_id" : "WA",
    "biggestCity" : "SEATTLE",
    "biggestPop" : 520096,
    "smallestCity" : "BENGE",
    "smallestPop" : 2
    }
  • 最终的$project阶段将_id字段重命名为state,并将biggestCitybiggestPopsmallestCitysmallestPop移动到biggestCitysmallestCity嵌套文档中。

此聚合操作的输出文档类似于以下内容

{
"state" : "RI",
"biggestCity" : {
"name" : "CRANSTON",
"pop" : 176404
},
"smallestCity" : {
"name" : "CLAYVILLE",
"pop" : 45
}
}
[1] 一个城市可以与多个邮政编码相关联,因为城市的不同部分可以各自有不同的邮政编码。

返回

分片集合