MongoDBのaggregateでマルチレベル$groupを実現する方法
MongoDBでマルチレベル(多段)の$groupを実装したい場合は、アグリゲーションフレームワーク(aggregate)を活用します。この記事では、実際にコレクションを作成し、複数の$groupステージを組み合わせて、年齢ごとに国別の件数をまとめる方法を解説します。
1. コレクションの作成とドキュメントの挿入
まず、サンプル用のコレクションを作成し、ドキュメントを挿入します。ここではdemo76というコレクションに、名前・年齢・国名を持つドキュメントを登録していきます。
> db.demo76.insertOne({ Name:"Chris","Age" : 21, "CountryName" : 'US' });
{
"acknowledged" : true,
"insertedId" : ObjectId("5e2bd3e571bf0181ecc42281")
}
> db.demo76.insertOne({ Name:"Chris","Age" : 21, "CountryName" : 'US' });
{
"acknowledged" : true,
"insertedId" : ObjectId("5e2bd3e571bf0181ecc42282")
}
> db.demo76.insertOne({ Name:"Chris","Age" : 23, "CountryName" : 'UK' });
{
"acknowledged" : true,
"insertedId" : ObjectId("5e2bd3e571bf0181ecc42283")
}
> db.demo76.insertOne({ Name:"Chris","Age" : 23, "CountryName" : 'UK' });
{
"acknowledged" : true,
"insertedId" : ObjectId("5e2bd3e571bf0181ecc42284")
}
> db.demo76.insertOne({ Name:"Chris","Age" : 21, "CountryName" : 'AUS' });
{
"acknowledged" : true,
"insertedId" : ObjectId("5e2bd3e571bf0181ecc42285")
}
> db.demo76.insertOne({ Name:"Chris","Age" : 21, "CountryName" : 'AUS' });
{
"acknowledged" : true,
"insertedId" : ObjectId("5e2bd3e571bf0181ecc42286")
}
> db.demo76.insertOne({ Name:"Chris","Age" : 23, "CountryName" : 'AUS' });
{
"acknowledged" : true,
"insertedId" : ObjectId("5e2bd3e571bf0181ecc42287")
}
> db.demo76.insertOne({ Name:"Chris","Age" : 21, "CountryName" : 'UK' });
{
"acknowledged" : true,
"insertedId" : ObjectId("5e2bd3e571bf0181ecc42288")
}2. find()メソッドで全ドキュメントを確認する
挿入したすべてのドキュメントは、find()メソッドを使って表示できます。
> db.demo76.find();
上記のクエリを実行すると、次のような出力が得られます。
{ "_id" : ObjectId("5e2bd3e571bf0181ecc42281"), "Name" : "Chris", "Age" : 21, "CountryName" : "US" }
{ "_id" : ObjectId("5e2bd3e571bf0181ecc42282"), "Name" : "Chris", "Age" : 21, "CountryName" : "US" }
{ "_id" : ObjectId("5e2bd3e571bf0181ecc42283"), "Name" : "Chris", "Age" : 23, "CountryName" : "UK" }
{ "_id" : ObjectId("5e2bd3e571bf0181ecc42284"), "Name" : "Chris", "Age" : 23, "CountryName" : "UK" }
{ "_id" : ObjectId("5e2bd3e571bf0181ecc42285"), "Name" : "Chris", "Age" : 21, "CountryName" : "AUS" }
{ "_id" : ObjectId("5e2bd3e571bf0181ecc42286"), "Name" : "Chris", "Age" : 21, "CountryName" : "AUS" }
{ "_id" : ObjectId("5e2bd3e571bf0181ecc42287"), "Name" : "Chris", "Age" : 23, "CountryName" : "AUS" }
{ "_id" : ObjectId("5e2bd3e571bf0181ecc42288"), "Name" : "Chris", "Age" : 21, "CountryName" : "UK" }3. マルチレベル$groupを実装するクエリ
それでは、本題であるマルチレベルの$groupを実装してみましょう。ポイントは以下の3つのステージを組み合わせることです。
- $match: 対象となるドキュメントを絞り込みます(ここでは「Name」が「Chris」のもの)。
- $group(1段階目): 「Age」と「CountryName」の組み合わせごとにグループ化し、
$sumで件数をカウントします。 - $group(2段階目): 「Age」だけで再グループ化し、
$pushで国名と件数のペアを配列にまとめます。
さらに、最後の$addFieldsステージで$arrayToObjectを使うことで、配列形式のデータを見やすいオブジェクト形式へ変換しています。
> db.demo76.aggregate([
... { "$match": { "Name": "Chris" }},
... { "$group": {
... "_id": { "Age": "$Age", "CountryName": "$CountryName" },
... "count": { "$sum": 1 }
... }},
... { "$group": {
... "_id": "$_id.Age",
... "CountryName": {
... "$push": {
... "k": "$_id.CountryName",
... "v": "$count"
... }
... }
... }},
... { "$addFields": {
... "CountryName": {
... "$arrayToObject": "$CountryName"
... }
... }}
... ]);4. 実行結果
上記のアグリゲーションパイプラインを実行すると、次のような出力が得られます。
{ "_id" : 23, "CountryName" : { "AUS" : 1, "UK" : 2 } }
{ "_id" : 21, "CountryName" : { "UK" : 1, "AUS" : 2, "US" : 2 } }この結果から、年齢23歳のドキュメントは「AUS」が1件、「UK」が2件、年齢21歳のドキュメントは「UK」が1件、「AUS」が2件、「US」が2件存在していることがひと目でわかります。
まとめ
このように、$groupを複数回組み合わせることで、MongoDBでもSQLのGROUP BYのように多段階の集約処理が可能になります。$pushや$arrayToObjectを併用すれば、ネストされた集計結果を読みやすい形に整形できるため、レポート作成やダッシュボード向けのデータ加工にも役立ちます。
-
MongoDBで複数のドキュメントをアトミックに一括更新する方法
MongoDBでは、update()メソッドに更新演算子の$setを組み合わせることで、条件に一致した複数のドキュメントをまとめてアトミックに更新できます。本記事では、サンプルコレクションを使いながら、その具体的な手順を解説します。 1. サンプルコレクションの作成 まず、insertOne()メソッドを使ってドキュメントを含むコレクションを作成します。 > db.demo699.insertOne({Name:Chris Brown}); { acknowledged : true, insertedId : ObjectId(5ea6e370551299a9f98c93a
-
MongoDBのupdateOne()とinsertOne()の違いと使い方を実例で解説
MongoDBには、コレクションへのドキュメント追加や更新を行うための便利なメソッドが多数用意されています。本記事では、その中でも特によく使われる insertOne() と updateOne() の役割の違いと具体的な使い方を、実際のコード例とともにわかりやすく解説します。insertOne():コレクションに新しいドキュメントを1件挿入するメソッドです。updateOne():クエリフィルタ(検索条件)に一致したドキュメントのうち、最初の1件のみを更新するメソッドです。insertOne()でサンプルコレクションを作成するまずは insertOne() を使って、サンプル用のコレクション