我正在尝试使用以下代码在现有的Mongo DB集合上执行多次插入
db.dados_meteo.aggregate( [
{ $match : { "POM" : "AguiardaBeira" } },
{ $project : {
_id : { $concat: [
"0001:",
{ $substr: [ "$DTM", 0, 4 ] },
{ $substr: [ "$DTM", 5, 2 ] },
{ $substr: [ "$DTM", 8, 2 ] },
{ $substr: [ "$DTM", 11, 2 ] },
{ $substr: [ "$DTM", 14, 2 ] },
{ $substr: [ "$DTM", 17, 2 ] }
] },
"RNF" : 1, "WET":1,"HMD":1,"TMP":1 } },
{ $out : "dados_meteo_reloaded" }
] )
但每次我更改$ match参数并进行新的聚合时,Mongo DB会删除以前的文档并插入新的结果。
你能帮帮我吗?
答案 0 :(得分:8)
简短的回答是“你不能”:
如果$ out操作指定的集合已经存在,那么在聚合完成后,$ out阶段将使用新的结果集合原子地替换现有集合。 $ out操作不会更改先前集合中存在的任何索引。如果聚合失败,$ out操作不会对预先存在的集合进行任何更改。
作为一种解决方法,您可以在聚合之后将$out
指定的集合文档复制到“永久”集合中,这可以通过多种方式之一(尽管不是理想的):
db.out.find().forEach(function(doc) {db.target.insert(doc)})
答案 1 :(得分:4)
从Mongo 4.2
开始,新的$merge
聚合运算符(类似于$out
)允许 合并 进入指定的集合:
输入以下内容:
db.source.insert([
{ "_id": "id_1", "a": 34 },
{ "_id": "id_3", "a": 38 },
{ "_id": "id_4", "a": 54 }
])
db.target.insert([
{ "_id": "id_1", "a": 12 },
{ "_id": "id_2", "a": 54 }
])
$merge
聚合阶段可以这样使用:
db.source.aggregate([
// { $whatever aggregation stage, for this example, we just keep records as is }
{ $merge: { into: "target" } }
])
产生:
// > db.target.find()
{ "_id" : "id_1", "a" : 34 }
{ "_id" : "id_2", "a" : 54 }
{ "_id" : "id_3", "a" : 38 }
{ "_id" : "id_4", "a" : 54 }
请注意,$merge
运算符随many options一起指定如何合并与现有记录冲突的插入记录。
在这种情况下(使用默认选项),这是
保留目标集合的现有文档({ "_id": "id_2", "a": 54 }
就是这种情况)
将尚不存在的文档从聚合管道的输出插入目标集合中(基于_id
-这是{ "_id" : "id_3", "a" : 38 }
的情况)
在聚合管道生成目标集合中存在的文档时替换目标集合的记录(基于_id
-{ "_id": "id_1", "a": 12 }
被{ "_id" : "id_1", "a" : 34 }
替换的情况)
答案 2 :(得分:1)
它不是最漂亮的东西,而是另一种替代语法(来自后期处理存档/附加操作)......
db.targetCollection.insertMany(db.runCommand(
{
aggregate: "sourceCollection",
pipeline:
[
{ $skip: 0 },
{ $limit: 5 },
{
$project:
{
myObject: "$$ROOT",
processedDate: { $add: [new ISODate(), 0] }
}
}
]
}).result)

我不确定这是如何与forEach变体叠加的,但我觉得它更直观易读。