使用邮政编码数据集进行汇总

在本页面

本文档中的示例使用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 pipelinestages组成,每个阶段处理文档沿管道传递时。文档按 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
}
  • $match阶段过滤这些分组的文档以仅输出totalPop值大于或等于 1000 万的那些文档。 $match阶段不会更改匹配的文档,但会输出未修改的匹配文档。

此聚合操作的等效SQL为:

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

See also

各 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阶段:

  • 第一个$group阶段按citystate的组合对文档进行分组,使用$sum表达式计算每个组合的填充量,并为每个citystate组合输出文档。 [1]

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

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

此聚合操作产生的文档类似于以下内容:

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

See also

按 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阶段组成:

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

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

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

  • 下一个$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]一个城市可以具有多个与之相关联的邮政编码,因为该城市的不同部分可以分别具有不同的邮政编码。