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

MongoDBの$unwind演算子でカウントを取得する方法

MongoDBの$unwindは、入力ドキュメント内の配列フィールドを分解し、配列の各要素に対して1つのドキュメントを出力する集計演算子です。この$unwindをaggregate()メソッドと組み合わせることで、要素ごとのカウントを効率的に取得できます。

本記事では、実際にコレクションを作成し、$unwindと$groupを組み合わせて年齢別のカウントを求める手順を解説します。

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

まず、ドキュメントを含むコレクションを作成します。以下の例では、「Details」フィールドの中に「Information」という配列を持つドキュメントを挿入しています。配列内には「Name」がnullの要素も含まれている点に注目してください。

> db.demo478.insertOne(
... {
...     "Details" : {
...        _id:1,
...        "Information" : [
...           {
...              "Name" : "Chris",
...              "Age":21
...           },
...           {
...              "Name" : "David",
...              "Age":23
...           },
...           {
...              "Name" : null,
...              "Age":22
...           },
...           {
...              "Name" : null,
...              "Age":24
...           }
...        ]
...    }
... }
... );
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e8204acb0f3fa88e2279092")
}
> db.demo478.insertOne(
... {
...     "Details" : {
...        _id:2,
...        "Information" : [
...           {
...              "Name" : "Bob",
...              "Age":21
...           },
...           {
...              "Name" : null,
...              "Age":20
...           }
...        ]
...    }
... }
... );
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e8204adb0f3fa88e2279093")
}

登録したドキュメントの確認

find()メソッドを使用すると、コレクション内のすべてのドキュメントを表示できます。

> db.demo478.find();

上記のコマンドを実行すると、以下のような出力が得られます。

{ "_id" : ObjectId("5e8204acb0f3fa88e2279092"), "Details" : { "_id" : 1, "Information" : [ {
"Name" : "Chris", "Age" : 21 }, { "Name" : "David", "Age" : 23 }, { "Name" : null, "Age" : 22 }, {
"Name" : null, "Age" : 24 } ] } }
{ "_id" : ObjectId("5e8204adb0f3fa88e2279093"), "Details" : { "_id" : 2, "Information" : [ {
"Name" : "Bob", "Age" : 21 }, { "Name" : null, "Age" : 20 } ] } }

$unwindでカウントを取得するクエリ

次に、$unwindを使ってカウントを取得する集計クエリを見ていきましょう。このクエリでは以下のステージを組み合わせています。

  • $unwind: 「Details.Information」配列を分解し、各要素を個別のドキュメントとして扱います。
  • $group: 年齢(Age)ごとにグループ化します。
  • $sumと$cond: Nameがnullより大きい値(つまりnull以外の名前が存在する場合)なら1、そうでなければ0を加算することでカウントします。
  • $sort: カウントの降順で結果を並べ替えます。
> db.demo478.aggregate([
...    { "$unwind": "$Details.Information" },
...    {
...       "$group" : {
...          "_id": "$Details.Information.Age",
...          "count" : {
...             "$sum": {
...                "$cond": [
...                   { "$gt": [ "$Details.Information.Name", null ] },
...                   1, 0
...                ]
...             }
...          }
...       }
...    },
... { "$sort" : { "count" : -1 } }
... ])

実行結果

上記のクエリを実行すると、年齢ごとにNameが設定されているドキュメントの数が出力されます。

{ "_id" : 21, "count" : 2 }
{ "_id" : 23, "count" : 1 }
{ "_id" : 24, "count" : 0 }
{ "_id" : 20, "count" : 0 }
{ "_id" : 22, "count" : 0 }

結果の解説

出力結果から以下のことが読み取れます。

  • 年齢21歳のグループには「Chris」と「Bob」の2件が該当するため、カウントは2です。
  • 年齢23歳のグループには「David」の1件のみが該当するため、カウントは1です。
  • 年齢20歳・22歳・24歳のグループでは、対応する要素のNameがすべてnullであるため、カウントは0になっています。

このように、$unwindで配列を分解し、$groupと$condを組み合わせることで、条件に合致する要素だけを柔軟にカウントできます。配列データを含むドキュメントの統計処理において、非常に有用なテクニックです。

  1. MongoDBの$groupと$sumを使ってドキュメント内の重複データの出現回数を取得する方法

    MongoDBでグループ集計を行い、同じ値が何回出現しているか(重複回数)を取得したい場合は、集計パイプラインの $group 演算子と $sum 演算子を組み合わせるのが定番の手法です。1. サンプルコレクションの作成まず、動作確認用に「Marks(点数)」フィールドを持つドキュメントをいくつか挿入したコレクションを作成します。> db.demo676.insertOne({Marks:87}); { acknowledged : true, insertedId : ObjectId(5ea41eed04263e90dac943f2) } > db.demo67

  2. MongoDB集計パイプラインで重複するNameフィールド値ごとの出現回数を取得する方法

    MongoDBでは、$unwindと$groupを組み合わせた集計(アグリゲーション)パイプラインを使うことで、配列内に存在する重複したフィールド値を名前ごとにグループ化し、それぞれの出現回数を簡単に取得できます。ここでは、具体的な例をもとにその手順を解説します。サンプルコレクションの作成まずは、ドキュメントを含むコレクションを作成してみましょう。以下の例では、demo558というコレクションに、国コードと複数人の受講科目情報を持つドキュメントを挿入します。> db.demo558.insertOne( ... { ... _id : 100, ... CountryCode