AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。

$unwind(集計ステージ)

$unwind

入力ドキュメントから配列フィールドを分解して、各要素のドキュメントを出力します。各出力ドキュメントは、配列フィールドの値が要素に置き換えられた入力ドキュメントです。

次の環境でホストされる配置には $unwind を使用できます。

  • MongoDB Atlas はクラウドでの MongoDB 配置のためのフルマネージド サービスです
  • MongoDB Enterprise: サブスクリプションベースの自己管理型 MongoDB バージョン

  • MongoDB Community: ソースが利用可能で、無料で使用できる自己管理型の MongoDB のバージョン

フィールドパス オペランドまたはドキュメント オペランドを渡して、配列フィールドを展開します。

$unwind に配列フィールドパスを渡すことができます。この構文では、フィールド値が null、欠落、または空の配列である場合、$unwind はドキュメントを出力しません。

{ $unwind: <field path> }

フィールド パスを指定するときは、フィールド名の前にドル記号$を付け、引用符で囲みます。

ドキュメントを$unwindに渡して、オプションを指定できます。

{ $unwind: { path: <field path>, includeArrayIndex: <string>, preserveNullAndEmptyArrays: <boolean> }}
フィールド
タイプ
説明

string

配列フィールドへのフィールドパス。フィールドパスを指定するには、フィールド名の前にドル記号$を付け、引用符で囲みます。

string

任意。要素の配列インデックスを保持する新しいフィールドの名前。名前をドル記号$で始めることはできません。

ブール値

任意。

  • true の場合、path が欠落しているか空の配列である場合、$unwind は出力ドキュメントから出力フィールドを省略します。値が null の場合、フィールドはnull のままになります。

  • false の場合、path が null、欠落、または空の配列である場合、$unwind はドキュメントを出力しません。

デフォルト値は false です。

path の値が配列に変換されない場合、$unwind は次のように動作します。

  • 値が欠落ではなく、nullでも、空の配列でもない場合、$unwind は値をそのまま使用して単一のドキュメントを出力します。

  • includeArrayIndex が指定されている場合、インデックスは配列入力の場合は 0、非配列入力の場合は null になります。リストの後半のドキュメントのインデックスは 0 より大きいです。

  • 値が欠落している場合、null、または空の配列の場合、$unwind は preserveNullAndEmptyArrays オプションに従います。includeArrayIndex が指定され、ドキュメントが保持されている場合、インデックスは null です。

入力ドキュメントに存在しないフィールド、またはフィールドが空の配列であるフィールドのパスを指定すると、$unwindはデフォルトで入力ドキュメントを無視し、その入力ドキュメントのドキュメントを出力しません。

配列フィールドが欠落しているか null か空の配列になっているドキュメントを出力するには、preserveNullAndEmptyArrays オプションを使用します。

このページの例では、sample_mflix データセット のデータを使用しています。自己管理型 MongoDB 配置にこのデータセットをロードする方法の詳細については、「サンプル データセットのロード」を参照してください。サンプル データベースに何らかの変更を加えた場合は、今ページの例を実行するには、データベースを削除して再作成する必要がある可能性があります。

次の集計では、$unwind ステージを使用して、Inception 映画ドキュメントの genres 配列にある要素ごとのドキュメントを出力します。

db.movies.aggregate( [ { $match: { title: "Inception" } }, { $project: { _id: 0, title: 1, genres: 1 } }, { $unwind: "$genres" }] )
[ { genres: 'Action', title: 'Inception' }, { genres: 'Mystery', title: 'Inception' }, { genres: 'Sci-Fi', title: 'Inception' }]

各出力ドキュメントは入力ドキュメントと同じですが、genres フィールドの値が元の genres 配列の単一の要素に置き換えられています。

次の集計では、4 つの映画ドキュメントとともに $unwind ステージを使用しています。2 つのドキュメント ("La porta del cielo" と "Neecha Nagar") には genres フィールドがありません。

db.movies.aggregate( [ { $match: { title: { $in: [ "Inception", "Brave", "La porta del cielo", "Neecha Nagar" ] } } }, { $project: { _id: 0, title: 1, genres: 1 } }, { $unwind: { path: "$genres" } }] )
[ { genres: 'Animation', title: 'Brave' }, { genres: 'Adventure', title: 'Brave' }, { genres: 'Comedy', title: 'Brave' }, { genres: 'Action', title: 'Inception' }, { genres: 'Mystery', title: 'Inception' }, { genres: 'Sci-Fi', title: 'Inception' }]
  • "Brave"および"Inception"ドキュメントでは、genresは入力された配列です。$unwindは各要素のドキュメントを返します。

  • "La porta del cielo" と "Neecha Nagar" のドキュメントには genres フィールドがないため、$unwind はそれらのドキュメントを返しません。

注意

{ path: <FIELD> } 構文は任意です。次の$unwind操作は同等です。

db.<COLLECTION>.aggregate( [ { $unwind: "<FIELD>" } ])
db.<COLLECTION>.aggregate( [ { $unwind: { path: "<FIELD>" } } ])

preserveNullAndEmptyArrays と includeArrayIndex の例では、sample_mflix.movies コレクションのドキュメントを使用します。

次の$unwind操作では、preserveNullAndEmptyArraysオプションを使用して、genresフィールドが欠落しているドキュメントを含めます。

db.movies.aggregate( [ { $match: { title: { $in: [ "Inception", "Brave", "La porta del cielo", "Neecha Nagar" ] } } }, { $project: { _id: 0, title: 1, genres: 1 } }, { $unwind: { path: "$genres", preserveNullAndEmptyArrays: true } }] )
[ { title: 'La porta del cielo' }, { title: 'Neecha Nagar' }, { genres: 'Animation', title: 'Brave' }, { genres: 'Adventure', title: 'Brave' }, { genres: 'Comedy', title: 'Brave' }, { genres: 'Action', title: 'Inception' }, { genres: 'Mystery', title: 'Inception' }, { genres: 'Sci-Fi', title: 'Inception' }]

次の $unwind 操作では、 includeArrayIndex オプションを使用して、出力に配列インデックスを含めます。

db.movies.aggregate( [ { $match: { title: "Inception" } }, { $project: { _id: 0, title: 1, genres: 1 } }, { $unwind: { path: "$genres", includeArrayIndex: "genreIndex" } }] )
[ { genres: 'Action', title: 'Inception', genreIndex: Long('0') }, { genres: 'Mystery', title: 'Inception', genreIndex: Long('1') }, { genres: 'Sci-Fi', title: 'Inception', genreIndex: Long('2') }]

次のパイプラインでは genres 配列を展開し、生成されたドキュメントをジャンルごとにグループ化して、各ジャンルの映画数をカウントします。

db.movies.aggregate( [ // First Stage { $match: { title: { $in: [ "The Dark Knight", "Inception", "Interstellar", "Brave" ] } } }, // Second Stage { $project: { _id: 0, title: 1, genres: 1 } }, // Third Stage { $unwind: "$genres" }, // Fourth Stage { $group: { _id: "$genres", movieCount: { $sum: 1 } } }, // Fifth Stage { $sort: { movieCount: -1 } }] )
[ { _id: 'Adventure', movieCount: 2 }, { _id: 'Action', movieCount: 2 }, { _id: 'Drama', movieCount: 2 }, { _id: 'Sci-Fi', movieCount: 2 }, { _id: 'Crime', movieCount: 1 }, { _id: 'Animation', movieCount: 1 }, { _id: 'Comedy', movieCount: 1 }, { _id: 'Mystery', movieCount: 1 }]

単一のパイプラインで $unwind を複数回適用して、複数の配列フィールドを含むドキュメントを展開できます。次の操作では、genres 配列を展開してから cast 配列を展開して、ジャンルと俳優の組み合わせごとにフラットなドキュメントを作成し、ジャンルごとにグループ化して各ジャンルのキャスト出演の合計をカウントします。

db.movies.aggregate( [ // First Stage { $match: { title: { $in: [ "Inception", "The Dark Knight", "Interstellar" ] } } }, // Second Stage { $project: { _id: 0, title: 1, genres: 1, cast: 1 } }, // Third Stage { $unwind: "$genres" }, // Fourth Stage { $unwind: "$cast" }, // Fifth Stage { $group: { _id: "$genres", castAppearances: { $sum: 1 } } }] )
[ { _id: 'Adventure', castAppearances: 4 }, { _id: 'Crime', castAppearances: 4 }, { _id: 'Action', castAppearances: 8 }, { _id: 'Drama', castAppearances: 8 }, { _id: 'Mystery', castAppearances: 4 }, { _id: 'Sci-Fi', castAppearances: 8 }]

関連するステージと式については、$group、$sum、$sort、および$multiplyを参照してください。

完全な例については、「配列とグループ データの展開」チュートリアルを参照してください。

このページを評価