如何将Mongo数据库聚合结果附加到现有集合?

Hug*_*ugo 7 mongodb aggregation-framework

我试图使用以下代码在现有的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" }
              ] )
Run Code Online (Sandbox Code Playgroud)

但每次我更改$ match参数并进行新的聚合时,Mongo DB会删除以前的文档并插入新的结果.

你可以帮帮我吗?

Ori*_*Dar 9

简短的回答是"你不能":

如果$ out操作指定的集合已经存在,那么在聚合完成后,$ out阶段将使用新结果集合原子地替换现有集合.$ out操作不会更改先前集合中存在的任何索引.如果聚合失败,$ out操作不会对预先存在的集合进行任何更改.

作为一种解决方法,您可以$out在聚合之后将指定的集合文档复制到"永久"集合,以多种方式之一(尽管不是理想的):

  • copyTo()是最简单的,请注意警告.不要使用其他的小结果.
  • 使用JS: db.out.find().forEach(function(doc) {db.target.insert(doc)})
  • 使用mongoexport/mongoimport

  • 不敢相信他们没有办法追加.这是一个拥有数百万资金的数据库?可怜. (27认同)
  • Ori,你的答案看起来不错。可能你想编辑它并添加这个选项 http://stackoverflow.com/a/37433640/2834978。db.col1.insert(db.col2.aggregate(...).toArray()) (2认同)

Xav*_*hot 7

从开始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 }
])
Run Code Online (Sandbox Code Playgroud)

$merge聚合阶段可被用作这样的:

db.source.aggregate([
  // { $whatever aggregation stage, for this example, we just keep records as is }
  { $merge: { into: "target" } }
])
Run Code Online (Sandbox Code Playgroud)

生产:

// > db.target.find()
{ "_id" : "id_1", "a" : 34 }
{ "_id" : "id_2", "a" : 54 }
{ "_id" : "id_3", "a" : 38 }
{ "_id" : "id_4", "a" : 54 }
Run Code Online (Sandbox Code Playgroud)

请注意,该$merge运算符带有许多选项来指定如何合并与现有记录冲突的插入记录。

在这种情况下(使用默认选项),这是:

  • 保留目标馆藏的现有文档(就是这种情况{ "_id": "id_2", "a": 54 }

  • 如果文档不存在,则将它们从聚合管道的输出插入目标集合中(基于_id-的情况{ "_id" : "id_3", "a" : 38 }

  • 当聚合管道生成目标集合中现有的文档时,将替换目标集合的记录(基于_id-的情况是,{ "_id": "id_1", "a": 12 }替换为{ "_id" : "id_1", "a" : 34 }

  • 从“Mongo 4.4”开始,“$merge”可以输出到正在聚合的同一集合:https://docs.mongodb.com/master/release-notes/4.4/#merge (4认同)