定義
互換性
次の環境でホストされる配置には $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 | 任意。要素の配列インデックスを保持する新しいフィールドの名前。名前をドル記号 | |
ブール値 | 任意。
デフォルト値は |
動作
非配列フィールドパス
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 配列の 1 つになっています。
欠落値または配列以外の値
次の集計では、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
preserveNullAndEmptyArrays と includeArrayIndex sample_mflix.moviesの例では、 コレクションのドキュメントが使用されます。
preserveNullAndEmptyArrays
次の$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' } ]
includeArrayIndex
次の$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 を 1 つのパイプライン内で複数回適用できます。次の操作では、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 } ]
このページのC#の例では、Atlasサンプルデータセット の sample_mflixデータベースを使用します。MongoDB Atlasクラスターを無料で作成して、サンプルデータセットをロードする方法については、 MongoDB .NET/ C#ドライバーのドキュメントの「 開始 」を参照してください。
次の Movie クラスは、sample_mflix.movies コレクション内のドキュメントをモデル化します。
public class Movie { public ObjectId Id { get; set; } public int Runtime { get; set; } public string Title { get; set; } public string Rated { get; set; } public List<string> Genres { get; set; } public string Plot { get; set; } public ImdbData Imdb { get; set; } public int Year { get; set; } public int Index { get; set; } public string[] Comments { get; set; } [] public DateTime LastUpdated { get; set; } }
注意
パスカルケースの ConventionPack
このページのC# クラスはプロパティ名にパスカルケースを使用していますが、MongoDB コレクションのフィールド名はキャメルケースを使用しています。この違いを考慮するために、アプリケーションが起動する際に次のコードを使用してConventionPackを登録してください。
var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() }; ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);
MongoDB .NET/ C#ドライバーを使用して$unwind ステージを集計パイプラインに追加するには、 PipelineDefinitionオブジェクトで Unwind() メソッドを呼び出します。
次の例では、各入力 Movieドキュメントの Genresフィールドを反復処理するパイプラインステージを作成しています。ステージは、Genresフィールドの各値に対して新しい Movieドキュメントを作成し、その Genresフィールドに入力ドキュメントの Genres 値を入力します。
var pipeline = new EmptyPipelineDefinition<Movie>() .Unwind(m => m.Genres);
AggregateUnwindOptionsオブジェクトを使用して、 Unwind()メソッドの動作をカスタマイズできます。
次の例では、前の例と同じ操作を実行しますが、次のオプションも含まれています。
PreserveNullAndEmptyArraysを指定すると、Genresフィールドに空の配列が含まれるドキュメントが出力に含まれるようになります。IncludeArrayIndexオプションは、各出力ドキュメントにIndexという名前の新しいフィールドを追加します。このフィールドの値は、入力ドキュメントのGenres配列内のGenresフィールドの値の配列インデックスです。
var pipeline = new EmptyPipelineDefinition<Movie>() .Unwind(m => m.Genres, new AggregateUnwindOptions<Movie>() { PreserveNullAndEmptyArrays = true, IncludeArrayIndex = new ExpressionFieldDefinition<Movie, int>( m => m.Index) });
このページのNode.js の例では、Atlasサンプルデータセット の sample_mflixデータベースを使用します。無料のMongoDB Atlas cluster を作成し、サンプルデータセットをロードする方法については、 MongoDB Node.jsドライバーのドキュメントの開始を参照してください。
MongoDB Node.jsドライバーを使用して $unwind ステージを集計パイプラインに追加するには、パイプラインオブジェクトで $unwind 演算子を使用します。
次の例では、各入力 movieドキュメントの genresフィールドを反復処理するパイプラインステージを作成しています。ステージは、genresフィールドの各値に対して新しい movieドキュメントを作成し、その genresフィールドに入力ドキュメントの genres 値を入力します。次に、この例では集計パイプラインを実行します。
const pipeline = [{ $unwind: "$genres" }]; const cursor = collection.aggregate(pipeline); return cursor;
$unwind メソッドの動作をカスタマイズできます。次の例では、前の例と同じ操作を実行しますが、次のオプションも含まれています。
preserveNullAndEmptyArraysを指定すると、genresフィールドに空の配列が含まれるドキュメントが出力に含まれるようになります。includeArrayIndex各出力ドキュメントにindexという名前の新しいフィールドを追加します。フィールドには、入力ドキュメントのgenresフィールド内のgenres値の配列インデックスが含まれます。
const pipeline = [ { $unwind: { path: "$genres", preserveNullAndEmptyArrays: true, includeArrayIndex: "index" } } ]; const cursor = collection.aggregate(pipeline); return cursor;
詳細
$group関連するステージと式については、 、 、$sum 、$sort $multiplyを参照してください。
完全な例については、「 配列とグループ データの展開 」チュートリアルを参照してください。