MongoDB聚合:$out
2023-12-30 15:51:44
$out
阶段将聚合管道产生的文档写入到指定的集合,从MongoDB4.4开始,支持指定数据库。$out
阶段必须放在聚合管道的最后,支持聚合结果任意大小的数据集。
警告:
如果指定的集合已经存在则会被替换。
语法
用法 1: 定数据库和集合名称
{ $out: { db: "<output-db>", coll: "<output-collection>" } }
-
db 指定数据库的名称:
- 对于标准的副本集,如果指定的数据库不存在,
$out
会自动创建。 - 对于分片集群,指定的数据库必须已经存在。
- 对于标准的副本集,如果指定的数据库不存在,
-
coll 指定集合的名称
用法 2:只指定集合名称
{ $out: "<output-collection>" } // 同一个数据库
直接为$out
指定输出集合的名称,输出到同一数据库。
注意
- 分片集合可以作为管道的输入,但是不能作为
$out
的输出集合,想要输出到分片集合可以使用$merge
。 $out
操作不能输出到副本集合。- 如果要修改带有Atlas Search索引的集合,必须先删除再重建索引,最好使用
$merge
代替$out
。
说明
创建新集合
如果指定的的集合不存在$out
可以创建新集合。在聚合未结束前集合不可见。如果聚合失败则不会创建集合。
替换已存在的集合
如果指定的集合已经存在,在聚合完成后$out
会使用新的结果替换原有集合,具体步骤如下:
- 创建一个临时的集合。
- 将现有集合索引复制到临时集合。
- 将聚合结果文档插入到临时集合。
- 调用
renameCollection
命令,并且dropTarget: True
,将临时集合更名为目标集合。
$out
操作不会修改原有集合的索引,如果聚合失败,也不会对原有集合做任何修改。
majority 读关注
从MongoDB4.2开始,可以为包含$out
阶段的聚合指定"majority"级别的读关注。
对mongodump
的影响
如果有客户端发起的聚合管道包含$out
阶段,则会导致带有--oplog
参数的’mongodump’执行失败。
一些限制
- 事务的限制。事务中的聚合管道不能使用
$out
。 - 时间序列集合的限制。聚合管道不能使用
$out
把结果输出到时间序列集合。 - 视图的限制。在视图定义中,不允许包含
$out
阶段。如果视图定义中包含内置的管道(如:视图定义包含$lookup
或facet
阶段),$out
阶段不能用于这些内置管道。 $lookup
阶段的限制。从MongoDB4.2开始,不能将$out
应用与$lookup
阶段的内嵌管道。$facet
阶段的限制。在$facet
阶段的内置管道不允许使用$out
阶段。$unionWith
阶段的限制。在$unionWidth
阶段的内置管道不允许使用$out
阶段。"linearizable"
读关注的限制。从MongoDB4.2开始,$out
阶段不能与读关注"linearizable"一起使用。这意味着,如果在db.collection.aggregate()
指定了读关注"linearizable",则不能在管道中使用$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
集合中的数据调整为按author
分组的标题,然后将结果写入test
数据库的authors
集合。
db.getSiblingDB("test").books.aggregate( [
{ $group : { _id : "$author", books: { $push: "$title" } } },
{ $out : "authors" }
] )
-
$group
阶段按照作者分组,使用$push
将同一作者的图书标题数组放入books
字段:{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] } { "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
-
$out
阶段将文档输出到test
数据库的authors
集合
运行查询命令:
db.getSiblingDB("test").authors.find()
得到结果:
{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }
输出到不同的数据库
以下聚合操作将test
数据库中books
集合中的数据调整为按author
分组的标题,然后将结果写入reporting
数据库的authors
集合。
db.getSiblingDB("test").books.aggregate( [
{ $group : { _id : "$author", books: { $push: "$title" } } },
{ $out : { db: "reporting", coll: "authors" } }
] )
-
$group
阶段按照作者分组,使用$push
将同一作者的图书标题数组放入books
字段:{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] } { "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
-
$out
阶段将文档输出到reporting
数据库的authors
集合
运行查询命令:
db.getSiblingDB("reporting").authors.find()
得到结果:
{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }
文章来源:https://blog.csdn.net/superatom01/article/details/135305483
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!