定義
$out集計パイプラインによって返されたドキュメントを受け取り、指定されたコレクションに書き込みます。出力データベースを指定できます。
$outステージはパイプラインの最後のステージである必要があります。$out演算子を使用すると、集計フレームワークは任意のサイズの結果セットを返すことができます。警告
$out操作で指定されたコレクションがすでに存在する場合、$outステージは集計の完了時に既存のコレクションを新しい結果のコレクションにアトミックに置き換えます。詳細については、 「既存のコレクションの置き換え」を参照してください。
構文
$out ステージの構文は次のとおりです。
$out出力コレクションのみを指定する文字列を採用できます(つまり、同じデータベース内のコレクションに出力します)。{ $out: "<output-collection>" } // Output collection is in the same database $out出力データベースと出力コレクションを指定するためのドキュメントを受け取れます。{ $out: { db: "<output-db>", coll: "<output-collection>" } } MongoDB 7.0.3と7.1以降では、
$outはドキュメントを取得し、 時系列コレクションに出力できます。{ $out: { db: "<output-db>", coll: "<output-collection>", timeseries: { timeField: "<field-name>", metaField: "<field-name>", granularity: "seconds" || "minutes" || "hours" , } } } フィールド説明db出力データベース名。
レプリカセットまたはスタンドアロンでは、出力データベースが存在しない場合、
$outによってデータベースも作成されます。
coll出力コレクション名。
timeseries時系列コレクションへの書き込みで使用する構成を指定するドキュメント。
timeFieldは必須です。その他のフィールドはすべてオプションです。timeField時系列コレクションへの書き込みで必要です。各時系列ドキュメントの日付を含むフィールドの名前。 時系列コレクション内のドキュメントには、
timeFieldの値として有効な BSON 日付が必要です。metaField任意。各時系列ドキュメントのメタデータを含むフィールドの名前。指定されたフィールドのメタデータは、一意の時系列ドキュメントにラベルを付けるために使用されるデータでなければなりません。メタデータを変更する必要はめったにありません。指定されたフィールドの名前を
_idまたはtimeseries.timeFieldと同じ名前にはできません。フィールドは任意のデータ型に指定できます。metaFieldフィールドは任意ですが、メタデータを使用するとクエリの最適化が向上します。 たとえば、MongoDBmetaFieldtimeFieldは新しいコレクションの フィールドと フィールドに 複合インデックス を自動的に作成します 。このフィールドに値を指定しない場合、データは時間のみに基づいてバケット化されます。granularityオプション。
bucketRoundingSecondsとbucketMaxSpanSecondsを設定する場合は使用しないでください。可能な値は
seconds(デフォルト)、minutes、およびhoursです。granularityを、連続する受信タイムスタンプ間の時間に最も近い値に設定します。これにより、MongoDB によるコレクションへのデータ保存方法が最適化され、パフォーマンスが向上します。粒度とバケット間隔の詳細については、「時系列データの粒度の設定」を参照してください。
bucketMaxSpanSecondsオプション。
granularityの代替としてbucketRoundingSecondsと一緒に使用します。同じバケツ内のタイムスタンプ間の最大時間を設定する。設定可能な値は 1~31536000 です。
バージョン 6.3 で追加。
bucketRoundingSecondsオプション。
granularityの代替としてbucketMaxSpanSecondsと一緒に使用します。bucketMaxSpanSecondsと等しくなければなりません。ドキュメントに新しいバケットが必要な場合、MongoDB ではドキュメントのタイムスタンプ値がこの間隔で切り捨てられ、バケットの最小時間が設定されます。
バージョン 6.3 で追加。
重要
シャーディングされたコレクションを出力コレクションとして指定することはできません。パイプラインの入力コレクションはシャーディングできます。シャーディングされたコレクションに出力するには、
$mergeを参照してください。$out演算子は、上限付きコレクションには結果を書き込みできません。MongoDB Searchインデックスを使用してコレクションを変更する場合は、まず検索インデックスを削除してから再作成する必要があります。代わりに、
$mergeの使用を検討してください。
との比較 $merge
MongoDB には、集計パイプラインの結果をコレクションに書き込むために、$merge と $out の 2 つのステージが備わっています。次に、2 つのステージの機能をまとめます。
$out | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
| ||||||||||
|
| ||||||||||
|
| ||||||||||
|
| ||||||||||
|
| ||||||||||
|
|
動作
セカンダリ レプリカセットのノードで実行される $out 読み取り操作
MongoDB 5.0 以降では、クラスター内のすべてのノードの featureCompatibilityVersion が 5.0 以上に設定され、かつ読み込み設定 (read preference) がセカンダリに設定されている場合に、レプリカセットのセカンダリ ノードで $out を実行できます。
$out ステートメントの読み取り操作はセカンダリ ノードで、書き込み操作はプライマリノードでのみ行われます。
すべてのドライバー バージョンが、レプリカセットのセカンダリノードへの $out 操作のターゲットをサポートしているわけではありません。ドライバーのドキュメントをチェックして、ドライバーがセカンダリ上で実行される $out のサポートをいつ追加したかを確認してください。
新しいコレクションの作成
$out 操作では、コレクションがまだ存在しない場合に新しいコレクションが作成されます。
コレクションは、集計が完了するまで表示されません。集約が失敗した場合、MongoDB ではコレクションが作成されません。
既存のコレクションの置き換え
出力コレクションがすでに存在する場合、$out ステージは集計の完了時にそれをアトミックに置き換えます。具体的には、$out 操作では次のことを行います。
一時コレクションを作成します。
既存のコレクションから一時コレクションにインデックスをコピーします。
ドキュメントを一時コレクションに挿入します。
dropTarget: trueでrenameCollectionコマンドを呼び出し、一時コレクションの名前を宛先コレクションに変更します。
指定されたコレクションが存在し、$out 操作で timeseries オプションが指定されている場合は、次の制限が適用されます。
既存のコレクションは時系列コレクションでなければならない。
既存のコレクションはビューであってはならない。
$outステージに含まれるtimeseriesオプションは、既存のコレクションのオプションと完全に一致する必要があります。
$out 操作では、前のコレクションに存在していたインデックスは変更されません。集計が失敗した場合、$out 操作では既存のコレクションは変更されません。
スキーマ検証エラー
collコレクションでスキーマ検証が使用されており、 validationActionがerrorに設定されている場合、 $outを含む無効なドキュメントを挿入するとエラーがスローされます。 $out操作では既存のコレクションは変更されず、集計パイプラインによって返されたドキュメントはcollコレクションに追加されません。
インデックスの制約
パイプラインによって生成されたドキュメントが、元の出力コレクションの _id フィールドのインデックスを含め、一意のインデックスに違反する場合、パイプラインは完了しません。
$out操作によってMongoDB Searchインデックスを含むコレクションが変更される場合は、検索インデックスを削除して再作成する必要があります。代わりに、$merge の使用を検討してください。
majority 読み取り保証(read concern)
$out ステージを含む集計に対して、読み取り保証 (read concern) レベル "majority" を指定できます。
相互作用: mongodump
--oplog で開始された mongodump は、ダンプ プロセス中にクライアントが $out を含む集計パイプラインを発行すると失敗します。詳細については、mongodump --oplog を参照してください。
制限事項
制限事項 | 説明 |
|---|---|
集約パイプラインでは、トランザクション内で | |
|
|
|
|
|
|
|
|
例
このページの例では、sample_mflixサンプルデータセットのデータを使用します。このデータセットを自己管理型MongoDB配置にロードする方法の詳細については、サンプルデータセットをロードする を参照してください。サンプルデータベースに変更を加えた場合、このページの例を実行するには、データベースを削除して再作成する必要がある場合があります。
同じデータベースへの出力
次の集計操作では、長さが 1000 分を超える映画をフィルタリングして、公開年ごとにグループ化し、タイトルを配列に収集します。パイプラインは結果を sample_mflixデータベース内の movies_by_yearコレクションに結果を書き込みます。
db.movies.aggregate( [ { $match : { runtime : { $gt : 1000 } } }, { $group : { _id : "$year", movies: { $push: "$title" } } }, { $out : "movies_by_year" } ] )
- 第 1 ステージ(
$match): $matchステージでは、 が より大きい映画がフィルタリングされます。runtime1000- 第 2 ステージ(
$group): - ステージは フィールドでグループ化し、
$groupyear$pushを使用して 配列フィールドにタイトルを追加します。movies - 第 3 ステージ(
$out): $outステージでは、ドキュメントがsample_mflixデータベースのmovies_by_yearコレクションに出力されます。
出力コレクション内のドキュメントを表示するには、次の操作を実行します。
db.movies_by_year.find().sort( { _id: 1 } )
[ { _id: 1978, movies: [ 'Centennial' ] }, { _id: 1994, movies: [ 'Baseball' ] } ]
別のデータベースへの出力
注意
レプリカセットまたはスタンドアロンでは、出力データベースが存在しない場合、$out によってデータベースも作成されます。
$out は、集計を実行する場所とは異なるデータベース内のコレクションに出力できます。
次の集計操作では、長さが 1000 分を超える映画をフィルタリングして、公開年ごとにグループ化し、タイトルを配列に収集します。パイプラインは結果を reportingデータベース内の movies_by_yearコレクションに結果を書き込みます。
db.movies.aggregate( [ { $match : { runtime : { $gt : 1000 } } }, { $group : { _id : "$year", movies: { $push: "$title" } } }, { $out : { db: "reporting", coll: "movies_by_year" } } ] )
- 第 1 ステージ(
$match): $matchステージでは、 が より大きい映画がフィルタリングされます。runtime1000- 第 2 ステージ(
$group): - ステージは フィールドでグループ化し、
$groupyear$pushを使用して 配列フィールドにタイトルを追加します。movies - 第 3 ステージ(
$out): $outステージでは、ドキュメントがreportingデータベースのmovies_by_yearコレクションに出力されます。
出力コレクション内のドキュメントを表示するには、次の操作を実行します。
db.movies_by_year.find().sort( { _id: 1 } )
[ { _id: 1978, movies: [ 'Centennial' ] }, { _id: 1994, movies: [ 'Baseball' ] } ]
このページのC#の例では、Atlasサンプルデータセット の sample_mflixデータベースを使用します。MongoDB Atlasクラスターを無料で作成して、サンプルデータセットをロードする方法については、 MongoDB .NET/ C#ドライバーのドキュメントの「 開始 」を参照してください。
次の Movie クラスは、sample_mflix.movies コレクション内のドキュメントをモデル化します。
[] public class Movie { [] public ObjectId Id { get; set; } [] public string Title { get; set; } = null!; [] public int? Year { get; set; } [] public int? Runtime { get; set; } [] public string? Rated { get; set; } [] public int Metacritic { get; set; } [] public string? Plot { get; set; } [] public string? Type { get; set; } [] public string[]? Cast { get; set; } [] public string[]? Directors { get; set; } [] public string[]? Writers { get; set; } [] public ImdbData? Imdb { get; set; } }
MongoDB .NET/ C#ドライバーを使用して$out ステージを集計パイプラインに追加するには、 オブジェクトでOut() PipelineDefinitionメソッドを呼び出します。
次の例では、 metacritic フィールドの値が 100 である映画を検索し、タイトルでソートし、結果を top_movies コレクションに書き込むパイプラインステージを作成しています。
var outCollection = _client .GetDatabase("sample_mflix") .GetCollection<Movie>("top_movies"); var pipeline = new EmptyPipelineDefinition<Movie>() .Match(Builders<Movie>.Filter.Eq(m => m.Metacritic, 100)) .Sort(Builders<Movie>.Sort.Ascending(m => m.Title)) .Out(outCollection);
{"_id": "...", "title": "Best Kept Secret", "runtime": "...", "metacritic": 100, "imdb": "..."} {"_id": "...", "title": "Boyhood", "runtime": "...", "metacritic": 100, "imdb": "..."} {"_id": "...", "title": "Fanny and Alexander", "runtime": "...", "metacritic": 100, "imdb": "..."} {"_id": "...", "title": "Lawrence of Arabia", "runtime": "...", "metacritic": 100, "imdb": "..."} {"_id": "...", "title": "The Conformist", "runtime": "...", "metacritic": 100, "imdb": "..."} {"_id": "...", "title": "The Godfather", "runtime": "...", "metacritic": 100, "imdb": "..."} {"_id": "...", "title": "The Leopard", "runtime": "...", "metacritic": 100, "imdb": "..."} {"_id": "...", "title": "The Wizard of Oz", "runtime": "...", "metacritic": 100, "imdb": "..."}
このページのNode.js の例では、Atlasサンプルデータセット の sample_mflixデータベースを使用します。無料のMongoDB Atlas cluster を作成し、サンプルデータセットをロードする方法については、 MongoDB Node.jsドライバーのドキュメントの開始を参照してください。
MongoDB Node.jsドライバーを使用して $out ステージを集計パイプラインに追加するには、パイプラインオブジェクトで $out 演算子を使用します。
次の例では、パイプラインの結果を movies コレクションに書き込むパイプラインステージを作成します。次に、この例は集計パイプラインを実行します。
const pipeline = [{ $out: { db: "sample_mflix", coll: "movies" } }]; const cursor = collection.aggregate(pipeline); return cursor;