Docs Menu
Docs Home
/
MongoDBマニュアル
/ / /

$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" ,
    }
    }
    }

    重要

    時系列の粒度の変更

    時系列コレクションを作成したら、collMod メソッドを使用してその粒度を変更できます。ただし、各バケットの対象期間は増やすことしかできず、減らすことはできません。

    フィールド
    説明

    db

    出力データベース名。

    coll

    出力コレクション名。

    timeseries

    時系列コレクションへの書き込みで使用する構成を指定するドキュメント。timeField は必須です。その他のフィールドはすべてオプションです。

    timeField

    時系列コレクションへの書き込みで必要です。... include::/includes/time-series/fact-time-field-description.rst

    metaField

    任意。各時系列ドキュメントのメタデータを含むフィールドの名前。指定されたフィールドのメタデータは、一意の時系列ドキュメントにラベルを付けるために使用されるデータでなければなりません。メタデータを変更する必要はめったにありません。指定されたフィールドの名前を _id または timeseries.timeField と同じ名前にはできません。フィールドは任意のデータ型に指定できます。

    metaFieldフィールドは任意ですが、メタデータを使用するとクエリの最適化が向上します。 たとえば、MongoDB metaFieldtimeFieldは新しいコレクションの フィールドと フィールドに 複合インデックス を自動的に作成します 。このフィールドに値を指定しない場合、データは時間のみに基づいてバケット化されます。

    granularity

    オプション。bucketRoundingSecondsbucketMaxSpanSecondsを設定する場合は使用しないでください。

    可能な値はseconds (デフォルト)、minutes 、およびhoursです。

    granularityを、連続する受信タイムスタンプ間の時間に最も近い値に設定します。これにより、MongoDB によるコレクションへのデータ保存方法が最適化され、パフォーマンスが向上します。

    粒度とバケット間隔の詳細については、「時系列データの粒度の設定」を参照してください。

    bucketMaxSpanSeconds

    オプション。granularityの代替としてbucketRoundingSecondsと一緒に使用します。同じバケツ内のタイムスタンプ間の最大時間を設定する。

    設定可能な値は 1~31536000 です。

    バージョン 6.3 で追加

    bucketRoundingSeconds

    オプション。granularityの代替としてbucketMaxSpanSecondsと一緒に使用します。bucketMaxSpanSecondsと等しくなければなりません。

    ドキュメントに新しいバケットが必要な場合、MongoDB ではドキュメントのタイムスタンプ値がこの間隔で切り捨てられ、バケットの最小時間が設定されます。

    バージョン 6.3 で追加

重要

  • シャーディングされたコレクションを出力コレクションとして指定することはできません。パイプラインの入力コレクションはシャーディングできます。シャーディングされたコレクションに出力するには、$merge を参照してください。

  • $out 演算子は、上限付きコレクションには結果を書き込みできません。

  • Atlas Searchインデックスを使用してコレクションを変更する場合は、まず検索インデックスを削除して再作成する必要があります。 代わりに、 $mergeの使用を検討してください。

MongoDB には、集計パイプラインの結果をコレクションに書き込むために、$merge$out の 2 つのステージが備わっています。次に、2 つのステージの機能をまとめます。

$out
  • 同じデータベースまたは異なるデータベース内のコレクションに出力できます。

  • 同じデータベースまたは異なるデータベース内のコレクションに出力できます。

  • 出力コレクションがまだ存在しない場合は、新しいコレクションを作成します。

  • 出力コレクションがまだ存在しない場合は、新しいコレクションを作成します。

  • 出力コレクションが既に存在する場合は、完全に置き換えます。

  • 結果(新しいドキュメントの挿入、ドキュメントのマージ、ドキュメントの置換、既存のドキュメントの保持、操作の失敗、カスタムアップデートパイプラインによるドキュメントの処理)を既存のコレクションに組み込むことができます。

    コレクションの内容を置換できます。ただし、集計結果にコレクション内に存在するすべてのドキュメントとの一致が含まれる場合に限ります。

  • シャーディングされたコレクションに出力できません。ただし、入力コレクションはシャーディングできます。

  • シャーディングされたコレクションに出力できます。入力コレクションもシャーディング可能です。

  • MongoDB 7.0.3 および 7.1 以降では、時系列コレクションに出力できます。

  • 時系列コレクションには出力できません。

  • SQL ステートメントに対応します。

    • INSERT INTO T2 SELECT * FROM T1
    • SELECT * INTO T2 FROM T1
  • SQL ステートメントに対応します。

    • MERGE T2 AS TARGET
      USING (SELECT * FROM T1) AS SOURCE
      ON MATCH (T2.ID = SOURCE.ID)
      WHEN MATCHED THEN
      UPDATE SET TARGET.FIELDX = SOURCE.FIELDY
      WHEN NOT MATCHED THEN
      INSERT (FIELDX)
      VALUES (SOURCE.FIELDY)
    • マテリアライズドビューの作成と更新

MongoDB 5.0 以降では、クラスター内のすべてのノードの featureCompatibilityVersion5.0 以上に設定され、かつ読み込み設定 (read preference) がセカンダリに設定されている場合に、レプリカセットのセカンダリ ノードで $out を実行できます。

$out ステートメントの読み取り操作はセカンダリ ノードで、書き込み操作はプライマリノードでのみ行われます。

すべてのドライバー バージョンが、レプリカセットのセカンダリノードへの $out 操作のターゲットをサポートしているわけではありません。ドライバーのドキュメントをチェックして、ドライバーがセカンダリ上で実行される $out のサポートをいつ追加したかを確認してください。

$out 操作では、コレクションがまだ存在しない場合に新しいコレクションが作成されます。

コレクションは、集計が完了するまで表示されません。集約が失敗した場合、MongoDB ではコレクションが作成されません。

$out 操作で指定されたコレクションがすでに存在する場合、集計の完了時に、$out ステージは既存のコレクションを新しい結果のコレクションにアトミックに置き換えます。具体的に言うと、$out 操作では

  1. 一時コレクションを作成します。

  2. 既存のコレクションから一時コレクションにインデックスをコピーします。

  3. ドキュメントを一時コレクションに挿入します。

  4. dropTarget: truerenameCollection コマンドを呼び出し、一時コレクションの名前を宛先コレクションに変更します。

指定されたコレクションが存在し、$out 操作で timeseries オプションが指定されている場合は、次の制限が適用されます。

  1. 既存のコレクションは時系列コレクションでなければならない。

  2. 既存のコレクションはビューであってはならない。

  3. $out ステージに含まれる timeseries オプションは、既存のコレクションのオプションと完全に一致する必要があります。

$out 操作では、前のコレクションに存在していたインデックスは変更されません。集計が失敗した場合、$out 操作では既存のコレクションは変更されません。

collコレクションでスキーマ検証が使用されており、 validationActionerrorに設定されている場合、 $outを含む無効なドキュメントを挿入するとエラーがスローされます。 $out操作では既存のコレクションは変更されず、集計パイプラインによって返されたドキュメントはcollコレクションに追加されません。

パイプラインによって生成されたドキュメントが、元の出力コレクションの _id フィールドのインデックスを含め、一意のインデックスに違反する場合、パイプラインは完了しません。

$out 操作によって Atlas Search インデックスを含むコレクションが変更される場合は、検索インデックスを削除して再作成する必要があります。代わりに、$merge の使用を検討してください。

$out ステージを含む集計に対して、読み取り保証 (read concern) レベル "majority" を指定できます。

--oplog で開始された mongodump は、ダンプ プロセス中にクライアントが $out を含む集計パイプラインを発行すると失敗します。詳細については、mongodump --oplog を参照してください。

制限事項
説明

集約パイプラインでは、トランザクション内で $out を使用できません。

より前のバージョンのMongoDBでは、集計パイプラインが7.0.3 $outを使用して時系列コレクションに出力することはできません。

$out ステージはビュー定義の一部としては使用できません。ビュー定義にネストされたパイプラインが含まれている(たとえば、ビュー定義に $lookup または $facet ステージが含まれている)場合、この $out ステージの制限はネストされたパイプラインにも適用されます。

$lookup ステージ

$lookup ステージのネストされたパイプライン$out ステージを含めることはできません。

$facet ステージ

$facet ステージのネストされたパイプライン$out ステージを含めることはできません。

$unionWith ステージ

$unionWith ステージのネストされたパイプライン$out ステージを含めることはできません。

"linearizable" 読み取り保証 (read concern)

$out ステージは読み取り保証 (read concern) "linearizable" と組み合わせて使用することはできません。db.collection.aggregate() に対して "linearizable" 読み取り保証 (read concern) を指定した場合、パイプライン内に $out ステージを含めることはできません。

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" ] }

戻る

$merge