郵便番号データセットによる集計
このドキュメントの例では、 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
フィールドには、都市名が保持されます。1 つの都市に複数の郵便番号を関連付けることができます。これは、都市の区画ごとに異なる郵便番号が付けられている場合があるためです。state
フィールドには 2 文字の州の略称が保持されます。pop
フィールドには人口が保持されます。loc
フィールドには、ロケーションが経度と緯度のペアで保持されます。
aggregate()
方式
以下のすべての例では、aggregate()
で mongosh
のヘルパーを使用しています。
aggregate()
メソッドは、集約パイプラインを使用してドキュメントを集約された結果に処理します。集約パイプラインはステージで構成され、各ステージではパイプラインを通過してドキュメントを処理します。ドキュメントは、ステージを順番に通過します。
mongosh
のaggregate()
メソッドは、aggregate
データベースコマンドを囲むラッパーを提供します。データ集計操作のより慣用的なインターフェイスについては、ドライバーのドキュメントを参照してください。
人口が1,000万人を超える州を返す
次の集計操作では、総人口が 1,000 万人を超えるすべての州を返します。
db.zipcodes.aggregate( [ { $group: { _id: "$state", totalPop: { $sum: "$pop" } } }, { $match: { totalPop: { $gte: 10*1000*1000 } } } ] )
この例では、集計パイプラインは、$group
ステージとそれに続く $match
ステージで構成されています。
$group
ステージでは、zipcode
コレクションのドキュメントをstate
フィールドごとにグループ化し、各州のtotalPop
フィールドを計算して、一意の州ごとにドキュメントを出力します。新しい州ごとのドキュメントには、
_id
フィールドとtotalPop
フィールドの 2 つのフィールドがあります。_id
フィールドには、state
(フィールド別のグループ)の値が含まれます。totalPop
フィールドは、各州の総人口を含む計算フィールドです。値を計算するために、$group
は$sum
演算子を使用して各州の人口フィールド(pop
)を追加します。$group
ステージの後、パイプライン内のドキュメントは次のようになります。{ "_id" : "AK", "totalPop" : 550043 } $match
ステージでは、グループ化されたドキュメントをフィルタリングして、totalPop
値が 1,000 万以上のドキュメントのみを出力します。$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 } 2 番目の
$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
ステージでは、ドキュメントをcity
とstate
の組み合わせでグループ化し、組み合わせごとにpop
の値のsum
を計算し、city
とstate
の組み合わせごとにドキュメントを出力します。パイプラインのこのステージでは、ドキュメントは次のようになります。
{ "_id" : { "state" : "CO", "city" : "EDGEWATER" }, "pop" : 13154 } $sort
ステージでは、pop
フィールドの値でパイプライン内のドキュメントを小さいものから大きいものへ、つまり昇順で並べます。この操作では、ドキュメントは変更されません。次の
$group
ステージでは、ソートされたドキュメントを_id.state
フィールド(つまり、_id
ドキュメント内のstate
フィールド)でグループ化し、各州のドキュメントを出力します。このステージでは、各州について次の 4 つのフィールドも計算されます。
$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] | 1 つの都市に複数の郵便番号を関連付けることができます。これは、都市の区画ごとに異なる郵便番号が付けられている場合があるためです。 |