MongoDBで複数ドキュメントを国・州・都市ごとに集計する方法
MongoDBの集計(アグリゲーション)操作は、複数のドキュメントから値をグループ化し、そのグループ化されたデータに対してさまざまな処理を実行して、単一の結果を返すための強力な機能です。本記事では、aggregate()メソッドと$groupステージを組み合わせて、コレクション内のドキュメントを「国 → 州 → 都市」の階層構造で集計する手順を解説します。
1. サンプルコレクションの作成
まずは動作確認用のコレクションを作成しましょう。insertOne()メソッドを使って、国・都市・州の情報を持つドキュメントを3件登録します。
> db.demo620.insertOne({"Country":"IND","City":"Delhi",state:"Delhi"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e9a8de96c954c74be91e6a1")
}
> db.demo620.insertOne({"Country":"IND","City":"Bangalore",state:"Karnataka"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e9a8e336c954c74be91e6a3")
}
> db.demo620.insertOne({"Country":"IND","City":"Mumbai",state:"Maharashtra"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e9a8e636c954c74be91e6a4")
}2. 登録したドキュメントの確認
find()メソッドを使用すると、コレクション内のすべてのドキュメントを表示できます。
> db.demo620.find();
実行すると、以下のような出力が得られます。
{ "_id" : ObjectId("5e9a8de96c954c74be91e6a1"), "Country" : "IND", "City" : "Delhi", "state" : "Delhi" }
{ "_id" : ObjectId("5e9a8e336c954c74be91e6a3"), "Country" : "IND", "City" : "Bangalore", "state" : "Karnataka" }
{ "_id" : ObjectId("5e9a8e636c954c74be91e6a4"), "Country" : "IND", "City" : "Mumbai", "state" : "Maharashtra" }3. 国・州・都市ごとに集計するクエリ
ここからが本題です。国・州・都市の3階層でデータをまとめるには、$groupステージを2段階に分けて使用します。
- 第1段階: 「国」と「州」の組み合わせでグループ化し、各グループに属する都市を
$addToSetで配列に収集します。 - 第2段階: さらに「国」単位でグループ化し、州とその都市リストをネストした形でまとめます。
具体的なクエリは以下の通りです。
> db.demo620.aggregate([
... { "$group": {
... "_id": {
... "Country": "$Country",
... "state": "$state"
... },
... "City": {
... "$addToSet": {
... "City": "$City"
... }
... }
... }},
... { "$group": {
... "_id": "$_id.Country",
... "states": {
... "$addToSet": {
... "state": "$_id.state",
... "City": "$City"
... }
... }
... }}
... ]).pretty();このクエリを実行すると、次のような結果が出力されます。
{
"_id" : "IND",
"states" : [
{
"state" : "Delhi",
"City" : [
{
"City" : "Delhi"
}
]
},
{
"state" : "Maharashtra",
"City" : [
{
"City" : "Mumbai"
}
]
},
{
"state" : "Karnataka",
"City" : [
{
"City" : "Bangalore"
}
]
}
]
}ポイント解説
この結果からわかるように、すべてのドキュメントが「IND(インド)」という国のもとにまとめられ、さらに州ごと(Delhi、Maharashtra、Karnataka)に分類され、それぞれの州に対応する都市が配列として格納されています。
$addToSetは重複する値を自動的に除外しながら配列を構築する演算子のため、同じ都市が複数回登録されていても結果には1度だけ現れます。階層的なデータ構造が必要なレポートやダッシュボードの実装において、この2段階の$groupパターンは非常に有用なので、ぜひ活用してみてください。
-
MongoDBで配列を持つ1つのドキュメントを新しいコレクションの複数ドキュメントに変換する方法
MongoDBでは、配列フィールドを持つ1つのドキュメントを、配列の各要素に対応する複数のドキュメントとして新しいコレクションに変換できます。この処理には、集計パイプラインのaggregate()と$unwind、そして結果を別のコレクションに出力するための$outを組み合わせて使用します。サンプルコレクションの作成まず、insertOne()メソッドを使ってドキュメントを挿入し、コレクションを作成しましょう。> db.demo757.insertOne( ... { ... id: 101, ... Name: [John, Bob, Chris]
-
MongoDBでコレクション内のドキュメントの各フィールドを数式を使って更新する方法
コレクション内のドキュメントの各フィールドを数式(計算式)で一括更新したい場合は、MongoDBの update() メソッドに $mul 演算子と全位置演算子 $[] を組み合わせて使用します。本記事では、配列内のすべての要素に対して特定のフィールドの値を乗算で更新する具体的な手順を解説します。サンプルコレクションの作成まず、insertOne() メソッドを使って、ドキュメントを含むコレクションを作成します。> db.demo749.insertOne({details:[{id:1,a:10},{id:2,a:5},{id:3,a:20}]}); { acknowledge