MongoDB集計パイプラインでドキュメント配列内のオブジェクトの各プロパティ値を合計する方法
MongoDBでドキュメント内の配列に格納されたオブジェクトの個別プロパティを合計するには、aggregate()メソッドを使用します。本記事では、$unwindや$groupといった集計パイプライン演算子を組み合わせて、プレイヤーごとのスコア合計を算出する具体的な手順を解説します。
サンプルコレクションの作成
まず、ドキュメントを格納したコレクションを作成しましょう。以下の例では、「PlayerScore(スコア)」と「PlayerName(プレイヤー名)」を持つオブジェクトを含む「Details」配列を持つドキュメントを挿入しています。
> db.demo131.insertOne(
... {
... "_id": 101,
... "Details": [
... {
... "PlayerScore": 500,
... "PlayerName": "Chris"
... },
... {
... "PlayerScore": 400,
... "PlayerName": "David"
... }
... ]
... }
... );
{ "acknowledged" : true, "insertedId" : 101 }
> db.demo131.insertOne(
... {
... "_id": 102,
... "Details": [
... {
... "PlayerScore": 600,
... "PlayerName": "Chris"
... },
... {
... "PlayerScore": 200,
... "PlayerName": "David"
... }
... ]
... }
... );
{ "acknowledged" : true, "insertedId" : 102 }
挿入したドキュメントの確認
find()メソッドを使えば、コレクション内のすべてのドキュメントを表示できます。
> db.demo131.find();
上記のコマンドを実行すると、次のような出力が得られます。
{ "_id" : 101, "Details" : [ { "PlayerScore" : 500, "PlayerName" : "Chris" }, { "PlayerScore" : 400, "PlayerName" : "David" } ] }
{ "_id" : 102, "Details" : [ { "PlayerScore" : 600, "PlayerName" : "Chris" }, { "PlayerScore" : 200, "PlayerName" : "David" } ] }
配列内のプロパティを合計する集計クエリ
続いて、配列内のオブジェクトが持つ個々のプロパティ(ここではPlayerScore)を、プレイヤー名ごとに合計するクエリを紹介します。
> db.demo131.aggregate([
... { $unwind: "$Details" },
... {
... $group: {
... _id:"$Details.PlayerName",
... Value:{$sum:"$Details.PlayerScore"}
... }
... },
... {
... $group: {
... _id: 0,
... Details:{ $push: {Details:"$_id",Value:"$Value"}}
... }
... },
... {
... $project:{Details:1,_id:0}
... } ])
クエリのポイント
- $unwind:Details配列を展開し、各要素を独立したドキュメントとして扱えるようにします。
- $group(1回目):PlayerNameごとにグループ化し、
$sumでPlayerScoreの合計値を算出します。 - $group(2回目):
$pushを使って、各プレイヤー名とその合計値を1つのDetails配列へまとめ直します。 - $project:必要なフィールドのみを出力し、
_idを除外して結果を見やすくします。
実行結果
このクエリを実行すると、次のような出力が得られます。
{ "Details" : [ { "Details" : "David", "Value" : 600 }, { "Details" : "Chris", "Value" : 1100 } ] }
結果を見ると、Chrisのスコアは500+600で1100、Davidのスコアは400+200で600となっており、複数ドキュメントにまたがる配列内データでも、プレイヤーごとの合計値が正しく集計できていることが確認できます。この手法は、売上明細やアクセスログなど、ネストされた配列データの統計処理にも幅広く応用できます。
-
MongoDBで配列フィールドを使ってドキュメントをフィルタリングする方法($elemMatch演算子の使い方)
MongoDBで配列内の要素に基づいてドキュメントをフィルタリングしたい場合、$elemMatch 演算子を使用します。$elemMatch は、指定した条件を満たす要素を少なくとも1つ含む配列フィールドを持つドキュメントを照合するための演算子です。この記事では、実際にコレクションを作成し、$elemMatch を使って配列条件でドキュメントを絞り込む手順を解説します。サンプルコレクションの作成まず、テスト用のコレクションにドキュメントを挿入してみましょう。ここでは、学生の名前と点数(Marks)を持つ details 配列を含むドキュメントを作成します。> db.demo453.ins
-
MongoDBで配列内のオブジェクトを更新する方法|update()と位置演算子($)の使い方
MongoDBで配列オブジェクトを更新するには?MongoDBでドキュメント内の配列オブジェクトを更新するには、update()メソッドを使用します。その際、ドット記法(dot notation)と位置演算子($)を組み合わせることがポイントです。位置演算子「$」は、クエリ条件に一致した配列要素を自動的に特定し、その要素だけを対象に更新処理を行ってくれます。それでは、実際にサンプルコレクションを作成しながら手順を見ていきましょう。1. コレクションの作成とドキュメントの挿入まず、insertOne()メソッドを使って、配列フィールド「details」を持つドキュメントを作成します。> d