MongoDB
 Computer >> コンピューター >  >> プログラミング >> MongoDB

MongoDBでネストされた配列を集約する方法:$addFieldsと$mapの活用

MongoDBでネストされた配列を集約するには、aggregate()メソッドを使用します。この記事では、$addFieldsや$mapといった集約パイプラインの演算子を組み合わせて、入れ子構造の配列から特定の条件に合致する要素を抽出する方法を、実際のコード例とともに解説します。

サンプルコレクションの作成

まず、ネストされた配列を持つドキュメントを含むコレクションを作成しましょう。insertOne()メソッドを使って、ドキュメントを挿入します。

> db.demo441.insertOne(
...     {
...       "Name" : "David",
...       "Age" : 21,
...       "details" : [
...          {
...            "id" : 1,
...            "CountryName" : "US",
...            "details1" : [
...               {
...                 "SubjectName" : "MySQL",
...                 "Score":56
...               },
...               {
...                 "SubjectName" : "MongoDB",
...                 "Score":78
...               }
...            ]
...          }
...      ]
...   }
... );
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e78cc05bbc41e36cc3caeb7")
}

このドキュメントでは、「details」という配列の中にさらに「details1」という配列が存在する、2階層のネスト構造になっています。

挿入したデータの確認

find()メソッドを使って、コレクション内のすべてのドキュメントを表示してみましょう。

> db.demo441.find();

実行すると、以下の出力が得られます。

{ "_id" : ObjectId("5e78cc05bbc41e36cc3caeb7"), "Name" : "David", "Age" : 21, "details" : [ { "id" : 1, "CountryName" : "US", "details1" : [ { "SubjectName" : "MySQL", "Score" : 56 }, { "SubjectName" : "MongoDB", "Score" : 78 } ] } ] }

ネストされた配列を集約するクエリ

それでは、ネストされた配列を集約するためのクエリを見ていきましょう。ここでは$addFieldsで新しいフィールドを作成し、その中で$mapを使って「details」配列の各要素を変換しています。

さらに、$let$arrayElemAtを組み合わせて、ネストされた「details1」配列の最後の要素を取得し、$cond(条件演算子)で「Score」が78である場合のみその要素を残す、という処理を行っています。

> db.demo441.aggregate([{
...    $addFields: {
...       ResultOfDetails: {
...          $map: {
...             input: "$details",
...             as: "output",
...             in: {
...                id: "$$output.id",
...                CountryName: "$$output.CountryName",
...                details1: {
...                   $let: {
...                      vars: {
...                         last: {
...                            $arrayElemAt: ["$$output.details1", -1]
...                         }
...                      },
...                      in: {
...                         $cond: [{
...                            $eq: ["$$last.Score", 78]
...                         },
...                         ["$$last"],
...                         []
...                      }
...                   }
...                }
...             }
...          }
...       }
...    }
... }]).pretty();

各演算子の役割

  • $addFields: 既存のドキュメントに新しいフィールド「ResultOfDetails」を追加します。元のフィールドは保持されます。
  • $map: 「details」配列の各要素に対して処理を適用し、新しい配列を生成します。
  • $arrayElemAt: 負のインデックス「-1」を指定することで、配列の最後の要素を取得できます。
  • $let: 一時的な変数「last」を定義し、後続の式内で再利用できるようにします。
  • $cond: 「$$last.Score」が78と等しい場合は該当要素を含む配列を返し、そうでなければ空の配列を返します。

クエリの実行結果

上記のクエリを実行すると、以下のような出力が得られます。

{
   "_id" : ObjectId("5e78cc05bbc41e36cc3caeb7"),
   "Name" : "David",
   "Age" : 21,
   "details" : [
      {
         "id" : 1,
         "CountryName" : "US",
         "details1" : [
            {
              "SubjectName" : "MySQL",
              "Score" : 56
            },
            {
              "SubjectName" : "MongoDB",
              "Score" : 78
            }
         ]
      }
   ],
   "ResultOfDetails" : [
      {
         "id" : 1,
         "CountryName" : "US",
         "details1" : [
            {
              "SubjectName" : "MongoDB",
              "Score" : 78
            }
         ]
      }  
   ]
}

結果をご覧ください。新しく追加された「ResultOfDetails」フィールドには、「Score」が78の「MongoDB」の要素だけが含まれています。このように、$mapと$arrayElemAt、$condなどを組み合わせることで、深くネストされた配列からも柔軟に目的のデータを抽出・集約することが可能です。

  1. MongoDBでネストされた配列をソートする方法:$unwindと$sortを活用したクエリ

    MongoDBでドキュメント内に格納されたネストされた配列(サブドキュメントの配列)をソートしたい場合、集計パイプライン(aggregate)を使い、$unwindで配列を展開した後に$sortで並べ替え、最後に$groupで再構成するのが定番のアプローチです。この記事では、実際にコレクションを作成しながら、ネストされた配列をスコア順にソートする手順を解説します。1. サンプルコレクションの作成まず、ネストされた配列「details」を持つドキュメントを挿入してコレクションを作成します。> db.demo505.insertOne( ... { ... details: [ ..

  2. MongoDBでネストされたドキュメントを更新する方法|位置演算子$を使った配列要素の更新手順

    MongoDBでは、ドキュメント内の配列に格納されたネストされた(入れ子の)ドキュメントも、位置演算子「$」を使うことで効率的に更新できます。この記事では、実際のコード例を通じて、配列内の特定のサブドキュメントを更新する手順をわかりやすく解説します。 1. サンプルコレクションの作成 まず、insertOne()メソッドを使用して、ネストされたドキュメントを含むコレクションを作成します。ここでは「Information」というフィールドに、複数のサブドキュメントを持つ配列を格納しています。 > db.demo595.insertOne( { Information: [ { _i