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

MongoDBでサブドキュメント内の配列をフィルタリングする方法【aggregate・$unwind活用】

MongoDBでサブドキュメント内の配列をフィルタリングしたい場合は、集計(aggregate)パイプラインを使用し、$matchを適用する前に$unwindで配列を展開する方法が一般的です。この記事では、実際にサンプルデータを作成しながら、手順をわかりやすく解説します。

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

まず、配列フィールド「L」を持つドキュメントを含むコレクション「filterArray」を作成します。以下のクエリを実行してください。

> db.filterArray.insertOne({ "L": [{ "N": 1 }, { "N": 2 }, { "N": 3 }, { "N": 4 }, { "N": 5 }] });

実行すると、次のような結果が返されます。

{
    "acknowledged" : true,
    "insertedId" : ObjectId("5c6d63f2734e98fc0a434aeb")
}

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

find()メソッドを使えば、コレクション内のドキュメントを表示できます。pretty()を付けると、整形された読みやすい形式で出力されます。

> db.filterArray.find().pretty();

実行結果は以下のとおりです。

{
    "_id" : ObjectId("5c6d63f2734e98fc0a434aeb"),
    "L" : [
        { "N" : 1 },
        { "N" : 2 },
        { "N" : 3 },
        { "N" : 4 },
        { "N" : 5 }
    ]
}

aggregateと$unwindで配列をフィルタリングする

それでは本題のフィルタリングです。次のクエリでは、aggregateパイプラインを使用し、$gt(〜より大きい)演算子によって、値が3より大きい要素のみを抽出しています。

> db.filterArray.aggregate(
...    { $match: { _id: ObjectId("5c6d63f2734e98fc0a434aeb") } },
...    { $unwind: '$L' },
...    { $match: { 'L.N': { $gt: 3 } } },
...    { $group: { _id: '$_id', subDocument: { $push: '$L.N' } } }
... ).pretty();

実行結果:

{
    "_id" : ObjectId("5c6d63f2734e98fc0a434aeb"),
    "subDocument" : [
        4,
        5
    ]
}

パイプラインの処理の流れ

  • $match:_idで対象ドキュメントを絞り込みます。
  • $unwind:配列「L」を要素ごとに個別のドキュメントへ展開します。
  • $match:展開後の各要素に対して「L.Nが3より大きい」という条件を適用します。
  • $group:元の_idごとに結果をまとめ、$pushで配列として再構築します。

補足:$filter演算子を使うより効率的な方法

MongoDB 3.2以降では、$filter集計演算子を使うことで、$unwindで配列を展開することなく直接フィルタリングできます。データ量が多い場合やネストが深い場合には、こちらの方がシンプルかつ高速です。

> db.filterArray.aggregate([
...    { $match: { _id: ObjectId("5c6d63f2734e98fc0a434aeb") } },
...    { $project: {
...       L: {
...           $filter: {
...              input: "$L",
...              as: "item",
...              cond: { $gt: ["$$item.N", 3] }
...           }
...       }
...    }}
... ]).pretty();

どちらの方法でも同じ結果が得られますので、使用しているMongoDBのバージョンやデータの規模に応じて、最適なアプローチを選択するとよいでしょう。

  1. MongoDBで配列フィールドを使ってドキュメントをフィルタリングする方法($elemMatch演算子の使い方)

    MongoDBで配列内の要素に基づいてドキュメントをフィルタリングしたい場合、$elemMatch 演算子を使用します。$elemMatch は、指定した条件を満たす要素を少なくとも1つ含む配列フィールドを持つドキュメントを照合するための演算子です。この記事では、実際にコレクションを作成し、$elemMatch を使って配列条件でドキュメントを絞り込む手順を解説します。サンプルコレクションの作成まず、テスト用のコレクションにドキュメントを挿入してみましょう。ここでは、学生の名前と点数(Marks)を持つ details 配列を含むドキュメントを作成します。> db.demo453.ins

  2. MongoDBのaggregate()で3階層にネストされた埋め込みドキュメントの配列をフィルタリングする方法

    MongoDBでネストされた配列をフィルタリングする基本アプローチMongoDBで3階層にネストされた埋め込みドキュメントの配列をフィルタリングするには、aggregate()メソッドを使用します。集計パイプラインの中で$unwindによって配列を展開し、$matchで条件に一致するドキュメントを絞り込むのが基本的な流れです。この記事では、実際のコード例を通じて具体的な手順を解説します。1. サンプルコレクションの作成まずは動作確認用のコレクションを作成し、ドキュメントを挿入してみましょう。> db.demo736.insertOne( ... { ... _id: