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

MongoDBでサブドキュメント(ネストされた配列)を並べ替えるクエリの書き方

MongoDBでは、集計パイプライン(Aggregation Pipeline)の各ステージを組み合わせることで、ドキュメント内のサブドキュメント(ネストされた配列要素)を特定の値に基づいて並べ替えることができます。本記事では、$unwind$project$sort$group を使って、配列内のサブドキュメントを「給与合計」の降順でソートする具体例を解説します。

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

まず、ネストされたサブドキュメントを含むコレクションを作成します。以下の例では、「Details」フィールドの中に複数の従業員情報があり、さらにその中に「EmployeeDetails」という配列を持つ階層構造のドキュメントを挿入しています。

> db.demo136.insertOne(
...    {
...       "Name":"Chris",
...       "Details":[
...          {
...             "Id":"101",
...             "EmployeeName":"Mike",
...             "EmployeeDetails":[
...                {
...                   "EmpId":1001,
...                   "Salary":1000
...                },
...                {
...                   "EmpId":1002,
...                   "Salary":2000
...                }
...             ]
...          },
...          {
...             "Id":"102",
...             "EmployeeName":"David",
...             "EmployeeDetails":[
...                   {
...                      "EmpId":1004,
...                      "Salary":4000
...                   },
...                   {
...                      "EmpId":1005,
...                      "Salary":5000
...                   }
...             ]
...          }
...       ]
...    }
... );
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e31b15cfdf09dd6d085399f")
}

登録済みドキュメントの確認

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

> db.demo136.find();

上記のコードを実行すると、次のような出力が得られます。

{
   "_id" : ObjectId("5e31b15cfdf09dd6d085399f"), "Name" : "Chris", "Details" : [
      { "Id" : "101", "EmployeeName" : "Mike", "EmployeeDetails" : [ { "EmpId" : 1001, "Salary" : 1000 },
      { "EmpId" : 1002, "Salary" : 2000 } ] },
      { "Id" : "102", "EmployeeName" : "David", "EmployeeDetails" : [ { "EmpId" : 1004, "Salary" : 4000 },
      { "EmpId" : 1005, "Salary" : 5000 } ] }
   ] 
}

サブドキュメントを並べ替える集計クエリ

続いて、サブドキュメントを給与合計の降順でソートするためのクエリを見ていきましょう。aggregate() メソッドを使用し、複数のステージを組み合わせて実現します。

> db.demo136.aggregate([
...    { $unwind: "$Details" },
...    {
...       $project: {
...          Name: 1,
...          Details: 1,
...          SalaryTotal: {
...             $sum: "$Details.EmployeeDetails.Salary"
...          }
...       }
...    },
...    { $sort: { SalaryTotal: -1 } },
...    {
...       $group: {
...          _id: "$_id",
...          Name: { $first: "$Name" },
...          Details: { $push: "$Details" }
...       }
...    }
... ]).pretty()

このクエリを実行すると、次のような結果が出力されます。

{
   "_id" : ObjectId("5e31b15cfdf09dd6d085399f"),
   "Name" : "Chris",
   "Details" : [
      {
         "Id" : "102",
         "EmployeeName" : "David",
         "EmployeeDetails" : [
            {
               "EmpId" : 1004,
               "Salary" : 4000
            },
            {
               "EmpId" : 1005,
               "Salary" : 5000
            }
         ]
      },
      {
         "Id" : "101",
         "EmployeeName" : "Mike",
         "EmployeeDetails" : [
            {
               "EmpId" : 1001,
               "Salary" : 1000
            },
            {
               "EmpId" : 1002,
               "Salary" : 2000
            }
         ]
      }
   ]
}

出力結果を見ると、元々は「Mike(Id: 101)」が先頭だった配列が、給与合計(9000)が大きい「David(Id: 102)」が先頭になるように並べ替えられていることが分かります。

クエリの仕組み解説

ここで使用している各ステージの役割は以下の通りです。

  • $unwind: 「Details」配列を展開し、各要素を独立したドキュメントとして扱えるようにします。
  • $project: 出力するフィールドを選択しつつ、$sum 演算子を使って各サブドキュメント内の「EmployeeDetails.Salary」の合計値を「SalaryTotal」として計算します。
  • $sort: 計算した「SalaryTotal」を基準に降順(-1)で並べ替えます。
  • $group: 元のドキュメントの _id をキーに再グループ化し、$push 演算子でソート後の順序を保持したまま「Details」配列を再構築します。

このように、配列を一度展開してソートし、再度まとめ直すという手法を使えば、MongoDBでもネストされたサブドキュメントの配列を自由に並べ替えることが可能です。集計パイプラインは応用範囲が広いため、さまざまなソート条件に合わせてカスタマイズしてみてください。

  1. MongoDBでサブドキュメントの配列をクエリする方法

    MongoDBでサブドキュメントの配列をクエリするには、集計パイプラインの$unwindを使用します。$unwindは、配列フィールドを展開し、配列の各要素ごとに個別のドキュメントを生成するステージです。これにより、配列内のサブドキュメントを個別にフィルタリングできるようになります。ここでは、大学の情報を含むコレクションを作成し、その中から特定の条件に一致するサブドキュメントを抽出する手順を解説します。コレクションの作成まず、insertOne()メソッドを使って、サブドキュメントの配列を含むドキュメントを挿入しましょう。> db.demo499.insertOne({... "

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

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