Definition定义
$outTakes the documents returned by the aggregation pipeline and writes them to a specified collection. You can specify the output database.获取聚合管道返回的文档并将其写入指定的集合。您可以指定输出数据库。The$outstage must be the last stage in the pipeline. The$outoperator lets the aggregation framework return result sets of any size.$out阶段必须是管道中的最后一个阶段。$out运算符允许聚合框架返回任何大小的结果集。Warning
If the collection specified by the如果$outoperation already exists, then the$outstage atomically replaces the existing collection with the new results collection upon completion of the aggregation.$out操作指定的集合已经存在,则$out阶段会在聚合完成后用新的结果集合原子性地替换现有集合。See Replace Existing Collection for details.有关详细信息,请参阅替换现有集合。
Syntax语法
The $out stage has the following syntax:$out阶段具有以下语法:
$outcan 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$outcan take a document to specify the output database as well as the output collection:可以使用文档来指定输出数据库和输出集合:{ $out: { db: "<output-db>", coll: "<output-collection>" } }Starting in MongoDB 7.0.3 and 7.1,从MongoDB 7.0.3和7.1开始,$outcan take a document to output to a time series collection:$out可以将文档输出到时间序列集合:{ $out:
{ db: "<output-db>", coll: "<output-collection>",
timeseries: {
timeField: "<field-name>",
metaField: "<field-name>",
granularity: "seconds" || "minutes" || "hours" ,
}
}
}Important
Changing Time Series Granularity改变时间序列粒度Field字段Description描述dbThe output database name.输出数据库名称。For a replica set or a standalone, if the output database does not exist,对于副本集或单机版副本,如果输出数据库不存在,$outalso creates the database.$out也会创建数据库。collThe output collection name.输出集合名称。timeseriesA document that specifies the configuration to use when writing to a time series collection. The指定写入时间序列集合时使用的配置的文档。timeFieldis required. All other fields are optional.timeField是必需的。所有其他字段都是可选的。timeFieldRequired when writing to a time series collection. The name of the field which contains the date in each time series document. Documents in a time series collection must have a valid BSON date as the value for the写入时间序列集合时需要。每个时间序列文档中包含日期的字段的名称。时间序列集合中的文档必须具有有效的BSON日期作为timeField.timeField的值。metaFieldOptional.可选。The name of the field which contains metadata in each time series document. The metadata in the specified field should be data that is used to label a unique series of documents.每个时间序列文档中包含元数据的字段的名称。指定字段中的元数据应该是用于标记一系列唯一文档的数据。The metadata should rarely, if ever, change The name of the specified field may not be元数据应该很少(如果有的话)更改。指定字段的名称可能不是_idor the same as thetimeseries.timeField. The field can be of any data type._id或与timeseries.timeField不同。该字段可以是任何数据类型。Although the虽然metaFieldfield is optional, using metadata can improve query optimization.metaField字段是可选的,但使用元数据可以改善查询优化。For example, MongoDB automatically creates a compound index on the例如,MongoDB会自动在metaFieldandtimeFieldfields for new collections.metaField和timeField字段上为新集合创建复合索引。If you do not provide a value for this field, the data is bucketed solely based on time.如果不为此字段提供值,则数据将仅基于时间进行分组。granularityOptional.可选。Do not use if setting如果设置bucketRoundingSecondsandbucketMaxSpanSeconds.bucketRoundingSeconds和bucketMaxSpanSeconds,则不要使用。Possible values are可能的值是seconds(default),minutes, andhours.seconds(默认值)、minutes和hours。Set将granularityto the value that most closely matches the time between consecutive incoming timestamps. This improves performance by optimizing how MongoDB stores data in the collection.granularity设置为与连续传入时间戳之间的时间最接近的值。这通过优化MongoDB在集合中存储数据的方式来提高性能。For more information on granularity and bucket intervals, see Set Granularity for Time Series Data.有关粒度和桶间隔的更多信息,请参阅设置时间序列数据的粒度。bucketMaxSpanSecondsOptional.可选。Use with使用bucketRoundingSecondsas an alternative togranularity.bucketRoundingSeconds作为granularity的替代方案。Sets the maximum time between timestamps in the same bucket.设置同一桶中时间戳之间的最大时间间隔。Possible values are 1-31536000.可能的值为1-31536000。New in version 6.3.在版本6.3中新增。bucketRoundingSecondsOptional.可选。Use with使用bucketMaxSpanSecondsas an alternative togranularity. Must be equal tobucketMaxSpanSeconds.bucketMaxSpanSeconds作为粒度的替代方案。必须等于bucketMaxSpanSeconds。When a document requires a new bucket, MongoDB rounds down the document's timestamp value by this interval to set the minimum time for the bucket.当文档需要新的桶时,MongoDB会按此间隔对文档的时间戳值进行四舍五入,以设置桶的最小时间。New in version 6.3.在版本6.3中新增。
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.$merge。The$outoperator cannot write results to a capped collection.$out运算符无法将结果写入封顶集合。If you modify a collection with a MongoDB Search index, you must first delete and then re-create the search index.如果使用MongoDB搜索索引修改集合,则必须先删除,然后重新创建搜索索引。Consider using考虑改用$mergeinstead.$merge。
Comparison with $merge与$merge的比较
$mergeMongoDB provides two stages, MongoDB提供了两个阶段,$merge and $out, for writing the results of the aggregation pipeline to a collection. The following summarizes the capabilities of the two stages:$merge和$out,用于将聚合管道的结果写入集合。以下总结了这两个阶段的能力:
$out | $merge |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Behaviors行为
$out Read Operations Run on Secondary Replica Set Members在辅助副本集成员上运行$out读取操作
Starting in MongoDB 5.0, 从MongoDB 5.0开始,如果集群中的所有节点都将$out can run on replica set secondary nodes if all the nodes in cluster have featureCompatibilityVersion set to 5.0 or higher and the Read Preference is set to secondary.featureCompatibilityVersion设置为5.0或更高,并且读取首选项设置为secondary,则$out可以在副本集secondary节点上运行。
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. Specifically, the $out operation:$out操作指定的集合已经存在,那么在聚合完成后,$out阶段会用新的结果集合原子性地替换现有集合。具体来说,$out操作:
- Creates a temp collection.
Copies the indexes from the existing collection to the temp collection.将索引从现有集合复制到临时集合。Inserts the documents into the temp collection.将文档插入到临时集合中。Calls the使用renameCollectioncommand withdropTarget: trueto rename the temp collection to the destination collection.dropTarget:true调用renameCollection命令,将临时集合重命名为目标集合。
If specified collection exists and the 如果指定的集合存在,并且$out operation specifies timeseries options, then the following restrictions apply:$out操作指定了时间序列选项,则适用以下限制:
The existing collection must be a time series collection.现有集合必须是时间序列集合。The existing collection must not be a view.现有集合不能是视图。Thetimeseriesoptions included in the$outstage must exactly match those on the existing collection.$out阶段中包含的timeseries选项必须与现有集合中的选项完全匹配。
The $out operation does not change any indexes that existed on the previous collection. If the aggregation fails, the $out operation makes no changes to the pre-existing collection.$out操作不会更改前一个集合上存在的任何索引。如果聚合失败,$out操作不会对预先存在的集合进行任何更改。
Schema Validation Errors架构验证错误
If your 如果您的coll collection uses schema validation and has validationAction set to error, inserting an invalid document with $out throws an error. coll集合使用模式验证,并且将validationAction设置为error,则使用$out插入无效文档会抛出错误。The $out operation makes no changes to the pre-existing collection and documents returned by the aggregation pipeline are not added to the coll collection.$out操作不会对预先存在的集合进行更改,聚合管道返回的文档也不会添加到coll集合中。
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 a MongoDB Search index, you must delete and re-create the search index. Consider using $merge instead.$out操作修改了具有MongoDB搜索索引的集合,则必须删除并重新创建搜索索引。考虑改用$merge。
majority Read Concern读取关注
You can specify read concern level 您可以为包含"majority" for an aggregation that includes an $out stage.$out阶段的聚合指定读取关注级别"majority"。
Interaction with mongodump与mongodump的互动
mongodumpA 如果客户端在转储过程中发出包含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限制
transactions | $out inside transactions.$out。 |
$out stage is not allowed as part of a view definition. $out阶段不允许作为视图定义的一部分。$lookup or $facet stage), this $out stage restriction applies to the nested pipelines as well.$lookup或$facet阶段),则此$out阶段限制也适用于嵌套管道。 | |
$lookup | $out stage in the $lookup stage's nested pipeline.$out阶段包含在$lookup阶段的嵌套管道中。 |
$facet stage | $facet$out stage.$out阶段。 |
$unionWith | $unionWith$out stage.$out阶段。 |
"linearizable" | $out stage cannot be used in conjunction with read concern "linearizable". $out阶段不能与读取关注"linearizable"结合使用。"linearizable" read concern for db.collection.aggregate(), you cannot include the $out stage in the pipeline.db.collection.aggregate()指定"linearizable"读取关注,则不能在管道中包含$out阶段。 |
Examples示例
MongoDB Shell
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集合中的数据进行枢轴转换,使标题按authors(作者)分组,然后将结果写入test数据库中的authors集合。
db.getSiblingDB("test").books.aggregate( [
{ $group : { _id : "$author", books: { $push: "$title" } } },
{ $out : "authors" }
] )
First Stage (第一阶段($group):$group):The$groupstage groups by theauthorsand uses$pushto add the titles to abooksarray field:$group阶段按authors分组,并使用$push将标题添加到books数组字段中:{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }
{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }Second Stage (第二阶段($out):$out):The$outstage outputs the documents to theauthorscollection in thetestdatabase.$out阶段将文档输出到测试数据库中的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也会创建数据库。
$out can output to a collection in a database different from where the aggregation is run.可以输出到与聚合运行位置不同的数据库中的集合。
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分组,然后将结果写入报告数据库中的作者集合:
db.getSiblingDB("test").books.aggregate( [
{ $group : { _id : "$author", books: { $push: "$title" } } },
{ $out : { db: "reporting", coll: "authors" } }
] )
First Stage (第一阶段($group):$group):The$groupstage groups by theauthorsand uses$pushto add the titles to abooksarray field:$group阶段按authors分组,并使用$push将标题添加到books数组字段中:{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }
{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }Second Stage (第二阶段($out):$out):The$outstage outputs the documents to theauthorscollection in thereportingdatabase.$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" ] }C#
The C# examples on this page use the 本页上的C#示例使用Atlas示例数据集中的sample_mflix database from the Atlas sample datasets. sample_mflix数据库。To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see Get Started in the MongoDB .NET/C# Driver documentation.要了解如何创建免费的MongoDB Atlas集群并加载示例数据集,请参阅MongoDB .NET/C#驱动程序文档中的入门。
The following 以下Movie class models the documents in the sample_mflix.movies collection:Movie类对sample_mflix.movies集合中的文档进行建模:
public class Movie
{
public ObjectId Id { get; set; }
public int Runtime { get; set; }
public string Title { get; set; }
public string Rated { get; set; }
public List<string> Genres { get; set; }
public string Plot { get; set; }
public ImdbData Imdb { get; set; }
public int Year { get; set; }
public int Index { get; set; }
public string[] Comments { get; set; }
[]
public DateTime LastUpdated { get; set; }
}
Note
ConventionPack for Pascal CasePascal大小写的约定包
The C# classes on this page use Pascal case for their property names, but the field names in the MongoDB collection use camel case. To account for this difference, you can use the following code to register a 此页面上的C#类使用Pascal大小写作为其属性名,但MongoDB集合中的字段名使用驼峰大小写。为了解释这种差异,您可以在应用程序启动时使用以下代码注册ConventionPack when your application starts:ConventionPack:
var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);To use the MongoDB .NET/C# driver to add a 要使用MongoDB .NET/C#驱动程序向聚合管道添加$out stage to an aggregation pipeline, call the Out() method on a PipelineDefinition object.$out阶段,请在PipelineDefinition对象上调用Out()方法。
The following example creates a pipeline stage that writes the results of the pipeline into the 以下示例创建了一个管道阶段,将管道的结果写入movies collection:movies集合:
var movieCollection = client
.GetDatabase("sample_mflix")
.GetCollection<Movie>("movies");
var pipeline = new EmptyPipelineDefinition<Movie>()
.Out(movieCollection);Node.js
The Node.js examples on this page use the 本页上的Node.js示例使用Atlas示例数据集中的sample_mflix database from the Atlas sample datasets. sample_mflix数据库。To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see Get Started in the MongoDB Node.js driver documentation.要了解如何创建免费的MongoDB Atlas集群并加载示例数据集,请参阅MongoDB Node.js驱动程序文档中的入门。
To use the MongoDB Node.js driver to add a 要使用MongoDB Node.js驱动程序向聚合管道添加$out stage to an aggregation pipeline, use the $out operator in a pipeline object.$out阶段,请在管道对象中使用$out运算符。
The following example creates a pipeline stage that writes the results of the pipeline into the 以下示例创建了一个管道阶段,将管道的结果写入movies collection. The example then runs the aggregation pipeline:movies集合。然后,该示例运行聚合管道:
const pipeline = [{ $out: { db: "sample_mflix", coll: "movies" } }];
const cursor = collection.aggregate(pipeline);
return cursor;