$out(集計)
定義
$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
時系列コレクションへの書き込みで必要です。... include::/includes/time-series/fact-time-field-description.rst
metaField
任意。各時系列ドキュメントのメタデータを含むフィールドの名前。指定されたフィールドのメタデータは、一意の時系列ドキュメントにラベルを付けるために使用されるデータでなければなりません。メタデータを変更する必要はめったにありません。指定されたフィールドの名前を
_id
またはtimeseries.timeField
と同じ名前にはできません。フィールドは任意のデータ型に指定できます。metaField
フィールドは任意ですが、メタデータを使用するとクエリの最適化が向上します。 たとえば、MongoDBmetaField
timeField
は新しいコレクションの フィールドと フィールドに 複合インデックス を自動的に作成します 。このフィールドに値を指定しない場合、データは時間のみに基づいてバケット化されます。granularity
オプション。
bucketRoundingSeconds
とbucketMaxSpanSeconds
を設定する場合は使用しないでください。可能な値は
seconds
(デフォルト)、minutes
、およびhours
です。granularity
を、連続する受信タイムスタンプ間の時間に最も近い値に設定します。これにより、MongoDB によるコレクションへのデータ保存方法が最適化され、パフォーマンスが向上します。粒度とバケット間隔の詳細については、「時系列データの粒度の設定」を参照してください。
bucketMaxSpanSeconds
オプション。
granularity
の代替としてbucketRoundingSeconds
と一緒に使用します。同じバケツ内のタイムスタンプ間の最大時間を設定する。設定可能な値は 1~31536000 です。
バージョン 6.3 で追加。
bucketRoundingSeconds
オプション。
granularity
の代替としてbucketMaxSpanSeconds
と一緒に使用します。bucketMaxSpanSeconds
と等しくなければなりません。ドキュメントに新しいバケットが必要な場合、MongoDB ではドキュメントのタイムスタンプ値がこの間隔で切り捨てられ、バケットの最小時間が設定されます。
バージョン 6.3 で追加。
重要
シャーディングされたコレクションを出力コレクションとして指定することはできません。パイプラインの入力コレクションはシャーディングできます。シャーディングされたコレクションに出力するには、
$merge
を参照してください。$out
演算子は、上限付きコレクションには結果を書き込みできません。Atlas 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
ステージは既存のコレクションを新しい結果のコレクションにアトミックに置き換えます。具体的に言うと、$out
操作では
一時コレクションを作成します。
既存のコレクションから一時コレクションにインデックスをコピーします。
ドキュメントを一時コレクションに挿入します。
dropTarget: true
でrenameCollection
コマンドを呼び出し、一時コレクションの名前を宛先コレクションに変更します。
指定されたコレクションが存在し、$out
操作で timeseries
オプションが指定されている場合は、次の制限が適用されます。
既存のコレクションは時系列コレクションでなければならない。
既存のコレクションはビューであってはならない。
$out
ステージに含まれるtimeseries
オプションは、既存のコレクションのオプションと完全に一致する必要があります。
$out
操作では、前のコレクションに存在していたインデックスは変更されません。集計が失敗した場合、$out
操作では既存のコレクションは変更されません。
スキーマ検証エラー
coll
コレクションでスキーマ検証が使用されており、 validationAction
がerror
に設定されている場合、 $out
を含む無効なドキュメントを挿入するとエラーがスローされます。 $out
操作では既存のコレクションは変更されず、集計パイプラインによって返されたドキュメントはcoll
コレクションに追加されません。
インデックスの制約
パイプラインによって生成されたドキュメントが、元の出力コレクションの _id
フィールドのインデックスを含め、一意のインデックスに違反する場合、パイプラインは完了しません。
$out
操作によって Atlas Search インデックスを含むコレクションが変更される場合は、検索インデックスを削除して再作成する必要があります。代わりに、$merge
の使用を検討してください。
majority
読み取り保証(read concern)
$out
ステージを含む集計に対して、読み取り保証 (read concern) レベル "majority"
を指定できます。
相互作用: mongodump
--oplog
で開始された mongodump
は、ダンプ プロセス中にクライアントが $out
を含む集計パイプラインを発行すると失敗します。詳細については、mongodump --oplog
を参照してください。
制限事項
制限事項 | 説明 |
---|---|
集約パイプラインでは、トランザクション内で $out を使用できません。 | |
$lookup ステージ | |
$facet ステージ | |
$unionWith ステージ | |
"linearizable" 読み取り保証 (read concern) |
|
例
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" ] }