$out (aggregation)

On this page本页内容

Definition定义

$out

Takes the documents returned by the aggregation pipeline and writes them to a specified collection. 获取聚合管道返回的文档并将其写入指定集合。Starting in MongoDB 4.4, you can specify the output database.从MongoDB 4.4开始,您可以指定输出数据库。

The $out stage must be the last stage in the pipeline. $out阶段必须是管道中的最后一个阶段。The $out operator lets the aggregation framework return result sets of any size.$out运算符允许聚合框架返回任意大小的结果集。

Warning警告

$out replaces the specified collection if it exists. 替换指定的集合(如果存在)。See Replace Existing Collection for details.有关详细信息,请参阅替换现有集合

Syntax语法

The $out stage has the following syntax:$out阶段语法如下:

  • Starting in MongoDB 4.4, $out can take a document to specify the output database as well as the output collection:从MongoDB 4.4开始,$out可以使用文档指定输出数据库和输出集合:

    { $out: { db: "<output-db>", coll: "<output-collection>" } }
    Field字段Description描述
    db

    The output database name.输出数据库名称。

    • For a replica set or a standalone, if the output database does not exist, $out also creates the database.对于副本集或独立数据库,如果输出数据库不存在,$out也会创建数据库。
    • For a sharded cluster, the specified output database must already exist.对于分片集群,指定的输出数据库必须已经存在。
    coll

    The output collection name.输出集合名称。

  • $out can take a string to specify only the output collection (i.e. output to a collection in the same database):可以使用字符串指定输出集合(即输出到同一数据库中的集合):

    { $out: "<output-collection>" } // Output collection is in the same database
Important重要
  • You cannot specify a sharded collection as the output collection. 不能将分片集合指定为输出集合。The input collection for a pipeline can be sharded. 可以分割管道的输入集合。To output to a sharded collection, see $merge(Available starting in MongoDB 4.2).要输出到分片集合,请参阅$merge(从MongoDB 4.2开始提供)。
  • The $out operator cannot write results to a capped collection.$out运算符无法将结果写入到封顶集合
  • If you modify a collection with an Atlas Search index, you must first delete and then re-create the search index. 如果使用Atlas搜索索引修改集合,则必须先删除,然后重新创建搜索索引。Consider using $merge instead.考虑改用$merge

Comparison with $merge$merge的比较

With the introduction of $merge in version 4.2, MongoDB provides two stages, $merge and $out, for writing the results of the aggregation pipeline to a collection. 随着4.2版引入$merge,MongoDB提供了两个阶段$merge$out,用于将聚合管道的结果写入集合。The following summarizes the capabilities of the two stages:以下总结了两个阶段的能力:

$out$merge
  • Available starting in MongoDB 2.6从MongoDB 2.6开始提供
  • Available starting in MongoDB 4.2从MongoDB 4.2开始提供
  • Can output to a collection in the same or, starting in MongoDB 4.4, different database.可以输出到同一数据库中的集合,或者从MongoDB 4.4开始,输出到不同的数据库中。
  • Can output to a collection in the same or different database.可以输出到相同或不同数据库中的集合。
  • Creates a new collection if the output collection does not already exist.如果输出集合不存在,则创建新集合。
  • Creates a new collection if the output collection does not already exist.如果输出集合不存在,则创建新集合。
  • Replaces the output collection completely if it already exists.如果输出集合已存在,则完全替换它。
  • Can incorporate results (insert new documents, merge documents, replace documents, keep existing documents, fail the operation, process documents with a custom update pipeline) into an existing collection.可以将结果(插入新文档、合并文档、替换文档、保留现有文档、操作失败、使用自定义更新管道处理文档)合并到现有集合中。

    Can replace the content of the collection but only if the aggregation results contain a match for all existing documents in the collection.可以替换集合的内容,但前提是聚合结果包含集合中所有现有文档的匹配项。

  • Cannot output to a sharded collection. 无法输出到分片集合。Input collection, however, can be sharded.然而,输入集合可以被分片。
  • Can output to a sharded collection. 可以输出到分片集合。Input collection can also be sharded.输入集合也可以被分片。
  • Corresponds to the SQL statements:对应于SQL语句:

    • INSERT INTO T2 SELECT * FROM T1
    • SELECT * INTO T2 FROM T1
  • Corresponds to the SQL statement:对应于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)
    • Create/Refresh Materialized Views创建/刷新物化视图

Behaviors行为

$out Read Operations Run on Secondary Replica Set Members$out读取操作在辅助副本集成员上运行

Starting in MongoDB 4.4, $out can run on replica set secondary nodes if all the nodes in cluster have featureCompatibilityVersion set to 4.4 or higher and the Read Preference is set to secondary.从MongoDB 4.4开始,如果集群中的所有节点都将featureCompatibilityVersion设置为4.4或更高,并且读取首选项设置为secondary,则$out可以在副本集辅助节点上运行。

Read operations of the $out statement occur on the secondary nodes, while the write operations occur only on the primary nodes.$out语句的读操作发生在辅助节点上,而写操作仅发生在主节点上。

Not all driver versions support targeting of $out operations to replica set secondary nodes. 并非所有驱动程序版本都支持将$out操作定位到副本集辅助节点。Check your driver documentation to see when your driver added support for $out running on a secondary.请查看驱动程序文档,了解驱动程序何时添加了对辅助系统上运行的$out的支持。

Create New Collection创建新集合

The $out operation creates a new collection if one does not already exist.$out操作将创建一个新集合(如果不存在)。

The collection is not visible until the aggregation completes. 在聚合完成之前,集合不可见。If the aggregation fails, MongoDB does not create the collection.如果聚合失败,MongoDB不会创建集合。

Replace Existing Collection替换现有集合

If the collection specified by the $out operation already exists, then upon completion of the aggregation, the $out stage atomically replaces the existing collection with the new results collection. 如果$out操作指定的集合已经存在,则在聚合完成后,$out阶段将用新的结果集合自动替换现有集合。Specifically, the $out operation:具体而言,$out操作:

  1. Creates a temp collection.创建临时集合。
  2. Copies the indexes from the existing collection to the temp collection.将索引从现有集合复制到临时集合。
  3. Inserts the documents into the temp collection.将文档插入临时集合。
  4. Calls the renameCollection command with dropTarget: true to rename the temp collection to the destination collection.使用dropTarget:true调用renameCollection命令,将临时集合重命名为目标集合。

The $out operation does not change any indexes that existed on the previous collection. $out操作不会更改先前集合中存在的任何索引。If the aggregation fails, the $out operation makes no changes to the pre-existing collection.如果聚合失败,$out操作不会对预先存在的集合进行任何更改。

Index Constraints索引约束

The pipeline will fail to complete if the documents produced by the pipeline would violate any unique indexes, including the index on the _id field of the original output collection.如果管道生成的文档违反任何唯一索引,包括原始输出集合的_id字段上的索引,则管道将无法完成。

If the $out operation modifies a collection with an Atlas Search index, you must delete and re-create the search index. 如果$out操作使用Atlas搜索索引修改集合,则必须删除并重新创建搜索索引。Consider using $merge instead.考虑改用$merge

majority Read Concern读取关注

Starting in MongoDB 4.2, you can specify read concern level "majority" for an aggregation that includes an $out stage.从MongoDB 4.2开始,您可以为包含$out阶段的聚合指定读关注级别"majority"

In MongoDB 4.0 and earlier, you cannot include the $out stage to use "majority" read concern for the aggregation.在MongoDB 4.0及更早版本中,您不能包含$out阶段来使用聚合的"majority"读取关注点。

Interaction with mongodumpmongodump的交互

A mongodump started with --oplog fails if a client issues an aggregation pipeline that includes $out during the dump process. 如果客户端在转储过程中发出包含$out的聚合管道,则以--oplog启动的mongodump将失败。See mongodump --oplog for more information.有关更多信息,请参阅mongodump --oplog

Restrictions限制

Restrictions限制Description描述
Transactions事务An aggregation pipeline cannot use $out inside transactions.聚合管道不能在事务内部使用$out
Time Series Collections时间序列集合An aggregation pipeline cannot use $out to output to a time series collection.聚合管道不能使用$out输出到时间序列集合。
View definition视图定义The $out stage is not allowed as part of a view definition. $out阶段不允许作为视图定义的一部分。If the view definition includes nested pipeline (e.g. the view definition includes $lookup or $facet stage), this $out stage restriction applies to the nested pipelines as well.如果视图定义包括嵌套管道(例如,视图定义包括$lookup$facet阶段),则$out阶段限制也适用于嵌套管道。
$lookup stage阶段Starting in 4.2, you cannot include the $out stage in the $lookup stage's nested pipeline.从4.2开始,您不能将$out阶段包含在$lookup阶段的嵌套管道中。
$facet stage阶段$facet stage's nested pipeline cannot include the $out stage.$facet阶段的嵌套管道不能包含$out阶段。
$unionWith stage阶段$unionWith stage's nested pipeline cannot include the $out stage.$unionWith阶段的嵌套管道不能包含$out阶段。
"linearizable" read concern关注阅读

Starting in MongoDB 4.2, the $out stage cannot be used in conjunction with read concern "linearizable". 从MongoDB 4.2开始,$out阶段不能与读取问题"linearizable"一起使用。That is, if you specify "linearizable" read concern for db.collection.aggregate(), you cannot include the $out stage in the pipeline.也就是说,如果为db.collection.aggregate()指定"linearizable"读取关注点,则不能在管道中包含$out阶段。

Examples示例

In the test database, create a collection books with the following documents: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 }
])

If the test database does not already exist, the insert operation creates the database as well as the books collection.如果test数据库不存在,插入操作将创建数据库和books集合。

Output to Same Database输出到同一数据库

The following aggregation operation pivots the data in the books collection in the test database to have titles grouped by authors and then writes the results to the authors collection, also in the test database.下面的聚合操作将test数据库中books集合中的数据旋转,使其具有按作者分组的标题,然后将结果写入test数据库中的authors集合。

db.getSiblingDB("test").books.aggregate( [
    { $group : { _id : "$author", books: { $push: "$title" } } },
    { $out : "authors" }
] )
First Stage第一阶段 ($group):

The $group stage groups by the authors and uses $push to add the titles to a books array field:$group阶段按authors分组,并使用$push将标题添加到books数组字段:

{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }
{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
Second Stage第二阶段 ($out):
The $out stage outputs the documents to the authors collection in the test database.$out阶段将文档输出到test数据库中的authors集合。

To view the documents in the output collection, run the following operation:要查看输出集合中的文档,请运行以下操作:

db.getSiblingDB("test").authors.find()

The collection contains the following documents:该集合包含以下文档:

{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }

Output to a Different Database输出到其他数据库

Note注意

For a replica set or a standalone, if the output database does not exist, $out also creates the database对于副本集或独立数据库,如果输出数据库不存在,$out也会创建数据库.

For a sharded cluster, the specified output database must already exist.对于分片集群,指定的输出数据库必须已经存在。

Starting in MongoDB 4.4, $out can output to a collection in a database different from where the aggregation is run.从MongoDB 4.4开始,$out可以输出到与运行聚合的数据库不同的数据库中的集合。

The following aggregation operation pivots the data in the books collection to have titles grouped by authors and then writes the results to the authors collection in the reporting database:以下聚合操作将books集合中的数据进行数据透视,使其具有按authors分组的标题,然后将结果写入reporting数据库中的作者集合:

db.getSiblingDB("test").books.aggregate( [
    { $group : { _id : "$author", books: { $push: "$title" } } },
    { $out : { db: "reporting", coll: "authors" } }
] )
First Stage第一阶段 ($group):

The $group stage groups by the authors and uses $push to add the titles to a books array field:$group阶段按authors分组,并使用$push将标题添加到books数组字段:

{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }
{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
Second Stage第二阶段 ($out):
The $out stage outputs the documents to the authors collection in the reporting database.$out阶段将文档输出到reporting数据库中的authors集合。

To view the documents in the output collection, run the following operation:要查看输出集合中的文档,请运行以下操作:

db.getSiblingDB("reporting").authors.find()

The collection contains the following documents:该集合包含以下文档:

{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }
←  $merge (aggregation)$planCacheStats →