定義
構文
$outステージの構文は次のとおりです。
$out出力データベースと出力コレクションを指定するためのドキュメントを受け取れます。{ $out: { db: "<output-db>", coll: "<output-collection>" } } フィールド説明出力データベース名。
レプリカセットまたはスタンドアロンの では、出力データベースが存在しない場合、
$outによってデータベースも作成されます。シャーディングされたクラスターの場合、指定された出力データベースがすでに存在している必要があります。
出力コレクション名。
$out出力コレクションのみを指定する文字列を採用できます(つまり、同じデータベース内のコレクションに出力します)。{ $out: "<output-collection>" } // Output collection is in the same database
重要
シャーディングされたコレクションを出力コレクションとして指定できません。 パイプラインの入力コレクションはシャーディングできます。 シャーディングされたコレクションに出力するには、
$mergeを参照してください(MongoDB 4.2 以降で利用可能)。Atlas Searchインデックスを使用してコレクションを変更する場合は、まず検索インデックスを削除して再作成する必要があります。 代わりに、
$mergeの使用を検討してください。
との比較 $merge
バージョン4.2での$mergeの導入により、 MongoDB には、集計パイプラインの結果をコレクションに書き込むために、 $mergeと$outの 2 つのステージが用意されています。 次に、2 つのステージの機能をまとめます。
|
| ||||||||||
|
| ||||||||||
|
| ||||||||||
|
| ||||||||||
|
|
動作
セカンダリ レプリカセットのノードで実行される $out 読み取り操作
MongoDB5.0 以降では、クラスター内のすべてのノードの$out featureCompatibilityVersion が5.0 以上に設定され、かつ 読み込み設定 (read preference) がセカンダリに設定されている場合に、レプリカセットのセカンダリ ノードで を実行できます。
$outステートメントの読み取り操作はセカンダリ ノードで実行され、書込み操作はプライマリ ノードでのみ実行されます。
すべてのドライバー バージョンが、レプリカセットのセカンダリ ノードへの$out操作のターゲットをサポートしているわけではありません。 ドライバーのドキュメントをチェックして、ドライバーがセカンダリ上で実行中の$outのサポートをいつ追加したかを確認してください。
新しいコレクションの作成
$out操作では、コレクションがまだ存在しない場合に新しいコレクションが作成されます。
コレクションは、集計が完了するまで表示されません。集約が失敗した場合、MongoDB ではコレクションが作成されません。
既存のコレクションの置き換え
$out操作で指定されたコレクションがすでに存在する場合、集計の完了時に、 $outステージは既存のコレクションを新しい結果のコレクションにアトミックに置き換えます。 具体的には、 $out操作は次のようになります。
一時コレクションを作成します。
既存のコレクションから一時コレクションにインデックスをコピーします。
ドキュメントを一時コレクションに挿入します。
dropTarget: trueでrenameCollectionコマンドを呼び出し、一時コレクションの名前を宛先コレクションに変更します。
$out操作では、前のコレクションに存在していたインデックスは変更されません。 集計が失敗した場合、 $out操作では既存のコレクションは変更されません。
スキーマ検証エラー
collコレクションでスキーマ検証が使用されており、 validationActionがerrorに設定されている場合、 $outを含む無効なドキュメントを挿入するとエラーがスローされます。 $out操作では既存のコレクションは変更されず、集計パイプラインによって返されたドキュメントはcollコレクションに追加されません。
インデックスの制約
パイプラインによって生成されたドキュメントが、元の出力コレクションの _id フィールドのインデックスを含め、一意のインデックスに違反する場合、パイプラインは完了しません。
$out操作によってAtlas Searchインデックスを含むコレクションが変更される場合は、検索インデックスを削除して再作成する必要があります。 代わりに、 $mergeの使用を検討してください。
majority 読み取り保証(read concern)
$out ステージを含む集計に対して、読み取り保証 (read concern) レベル "majority" を指定できます。
相互作用: mongodump
mongodumpで開始された は、ダンプ--oplog$out プロセス中にクライアントが を含む集計パイプラインを発行すると失敗します。詳しくは、 mongodump --oplogを参照してください。
制限事項
制限事項 | 説明 |
|---|---|
集計パイプラインでは、 | |
| 4.2以降では、 |
|
|
|
|
|
|
例
test データベースに、次のドキュメントを含むコレクション、books を作成します。
db.getSiblingDB("test").books.insertMany([ { "_id" : 8751, "title" : "The Banquet", "author" : "Dante", "copies" : 2 }, { "_id" : 8752, "title" : "Divine Comedy", "author" : "Dante", "copies" : 1 }, { "_id" : 8645, "title" : "Eclogues", "author" : "Dante", "copies" : 2 }, { "_id" : 7000, "title" : "The Odyssey", "author" : "Homer", "copies" : 10 }, { "_id" : 7020, "title" : "Iliad", "author" : "Homer", "copies" : 10 } ])
test データベースがまだ存在しない場合は、挿入操作によってデータベースと books コレクションが作成されます。
同じデータベースへの出力
次の集計操作では、test データベース内の books コレクションのデータをピボットして、著者ごとにタイトルをグループ化し、その結果を authors コレクション(同じ test データベース内)に書き込みます。
db.getSiblingDB("test").books.aggregate( [ { $group : { _id : "$author", books: { $push: "$title" } } }, { $out : "authors" } ] )
- 第 1 ステージ(
$group): $groupステージではauthorsでグループ化を行い、$pushを使用してbooks配列フィールドにタイトルを追加します。{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] } { "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] } - 第 2 ステージ(
$out): $outステージはドキュメントをtestデータベースのauthorsコレクションに出力します。
出力コレクション内のドキュメントを表示するには、次の操作を実行します。
db.getSiblingDB("test").authors.find()
コレクションには、次のドキュメントが含まれます。
{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] } { "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }
別のデータベースへの出力
注意
レプリカセットまたはスタンドアロンでは、出力データベースが存在しない場合、 $outによってデータベースも作成されます。
シャーディングされたクラスターの場合、指定された出力データベースがすでに存在している必要があります。
$out 集計が実行される場所とは異なるデータベース内のコレクションに出力できます。
次の集計操作では、books コレクションのデータをピボットして、著者ごとにタイトルをグループ化し、その結果を reporting データベース内の authors コレクションに書き込みます。
db.getSiblingDB("test").books.aggregate( [ { $group : { _id : "$author", books: { $push: "$title" } } }, { $out : { db: "reporting", coll: "authors" } } ] )
- 第 1 ステージ(
$group): $groupステージではauthorsでグループ化を行い、$pushを使用してbooks配列フィールドにタイトルを追加します。{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] } { "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] } - 第 2 ステージ(
$out): $outステージはドキュメントをreportingデータベースのauthorsコレクションに出力します。
出力コレクション内のドキュメントを表示するには、次の操作を実行します。
db.getSiblingDB("reporting").authors.find()
コレクションには、次のドキュメントが含まれます。
{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] } { "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }