MongoDBで複数列によるグループ化と合計を実行し、重複IDの合計点数を計算する方法
MongoDBでは、aggregate()メソッドと$group演算子を組み合わせることで、複数の列を基準にデータをグループ化し、重複するIDごとの合計値を簡単に計算できます。本記事では、実際のコレクションを作成しながら、その手順を具体的に解説します。
サンプルコレクションの作成
まず、ドキュメントを含むコレクションを作成しましょう。ここでは、学生のID・名前・点数を格納する「demo627」というコレクションを使用します。
> db.demo627.insertOne({id:101,"Name":"Chris","Marks":54});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e9acb306c954c74be91e6b2")
}
> db.demo627.insertOne({id:102,"Name":"Bob","Marks":74});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e9acb3c6c954c74be91e6b3")
}
> db.demo627.insertOne({id:101,"Name":"Chris","Marks":87});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e9acb426c954c74be91e6b4")
}
> db.demo627.insertOne({id:102,"Name":"Mike","Marks":70});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e9acb4b6c954c74be91e6b5")
}上記のように、同じID(101や102)を持つドキュメントが複数存在していることがわかります。
登録したドキュメントの確認
find()メソッドを使って、コレクション内のすべてのドキュメントを表示してみましょう。
> db.demo627.find();
このクエリを実行すると、次のような出力が得られます。
{ "_id" : ObjectId("5e9acb306c954c74be91e6b2"), "id" : 101, "Name" : "Chris", "Marks" : 54 }
{ "_id" : ObjectId("5e9acb3c6c954c74be91e6b3"), "id" : 102, "Name" : "Bob", "Marks" : 74 }
{ "_id" : ObjectId("5e9acb426c954c74be91e6b4"), "id" : 101, "Name" : "Chris", "Marks" : 87 }
{ "_id" : ObjectId("5e9acb4b6c954c74be91e6b5"), "id" : 102, "Name" : "Mike", "Marks" : 70 }複数列でのグループ化と合計計算のクエリ
それでは、MongoDBで複数の列(ここでは「id」と「Name」)を基準にグループ化し、重複するIDごとの合計点数を計算するクエリを見ていきましょう。
> db.demo627.aggregate([
... { "$group": {
... "_id": {
... "id" : "$id",
... "Name":"$Name"
... },
... "Marks": { "$sum": "$Marks" }
... }},
... { "$group": {
... "_id": {
... "id" : "$_id.id",
... "Name": "$_id.Name"
... },
...
... "TotalMarks": { "$sum": "$Marks" }
... }}
... ], { "allowDiskUse": true }
... );クエリのポイント解説
- $groupステージ: 「id」と「Name」の組み合わせを一意のキーとしてグループ化し、
$sum演算子で各グループの「Marks」を合計しています。 - 二段階の$group: 最初の$groupで中間集計を行い、2番目の$groupで最終的な合計点数(TotalMarks)を算出しています。
- allowDiskUseオプション: 大量のデータを扱う場合に、集計処理がメモリ制限を超えてもディスクを使用して処理を継続できるようにするオプションです。
実行結果
このクエリを実行すると、次のような出力が得られます。
{ "_id" : { "id" : 101, "Name" : "Chris" }, "TotalMarks" : 141 }
{ "_id" : { "id" : 102, "Name" : "Bob" }, "TotalMarks" : 74 }
{ "_id" : { "id" : 102, "Name" : "Mike" }, "TotalMarks" : 70 }結果を見ると、IDが101の「Chris」は54点と87点の合計である141点、IDが102の「Bob」は74点、「Mike」は70点として、それぞれ正しくグループ化・集計されていることが確認できます。このように、aggregate()と$groupを活用すれば、重複するIDを持つデータでも柔軟に集計処理が可能です。
-
MongoDBの集計パイプラインで複数フィールドをカウントする方法($facet活用)
MongoDBで複数のフィールドごとにドキュメントをカウントしたい場合、$facet演算子を使うのが効果的です。$facetは、同じ入力ドキュメント群に対して、単一のステージ内で複数の集計パイプラインを同時に処理できる強力な機能です。この記事では、実際にコレクションを作成し、$facetを組み合わせた集計クエリで複数フィールドの値をカウントする手順を解説します。1. サンプルコレクションの作成まず、insertOne()メソッドを使ってサンプルドキュメントを挿入します。各ドキュメントにはdetails1・details2・details3という3つのネストされたフィールドを持たせます。>
-
MongoDBのaggregateで$groupを使って複数の集計結果を一度に取得する方法
MongoDBでは、$facetと$groupを組み合わせることで、1回のaggregateクエリで複数の集計結果を同時に取得できます。この記事では、実際のコード例を通じてその方法を解説します。サンプルコレクションの作成まず、ドキュメントを含むコレクションを作成しましょう。以下のようにinsertOne()メソッドを使ってデータを挿入します。> db.demo765.insertOne( ... { ... Name:John, ... Category:ComputerScience, ... SubjectName:MongoDB,