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

$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 配列の 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 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 を 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; }
[BsonElement("lastupdated")]
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を参照してください。

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

このページを評価