MongoDB-更新以展平每个文档的内部数组

时间:2019-10-17 17:57:34

标签: mongodb

我有一个文档集合,其中的一个内部属性是一个对象数组,但是这些对象被错误地存储在内部数组中,例如以下实例,特别是“ recs”属性:

{
  "_id": ObjectId("5d52e851b412ca0001f10038"),
  "idIntegracaoContabil": NumberLong(6583),
  "protocol": "489dsad3-b075-4bc2-8631-9c01cc778e75",
  "content": {
    "idInteg": "1f2bd0d3b48978c286319c01cc778e75",
    "recs": [
      [
        {
          "desc": "Lorem ipsum dolor sit amet",
          "type": "TYPE1"
        },
        {
          "desc": "Sed ut perspiciatis unde omnis iste natus error",
          "type": "TYPE2"
        }
      ],
      [
        {
          "desc": "Et harum quidem rerum facilis est et expedita distinctio",
          "type": "TYPE3"
        }
      ]
    ]
  },
  "createdBy": "admin"
}

现在,我需要更新此集合的所有元素,将这些数组展平为desc / type对象的单个数组。我已经查询过应该使用$ unwind之类的聚合函数来获得此结果,但是我不知道如何在更新中做到这一点。

1 个答案:

答案 0 :(得分:0)

如果您的MongoDB版本> = 3.4,我相信最好的方法是使用运算符$reduce来使数组变平。

您可以这样做:

db.your_collection.aggregate(
  [
    {
      $project: {
        "_id": 1,
        "idIntegracaoContabil": 1,
        "protocol": 1,
        "content.idInteg": 1,
        "content.recs": {
            $reduce: {
                input: '$content.recs',
                initialValue: [],
                in: {$concatArrays: ['$$value', '$$this']}
            }
        },
        "createdBy": 1,  
      }
    },
    {$out: "your_collection"}

  ]
)

如您所见,在这种情况下,您需要将所有字段添加到投影中,以便使用$out

保存文档的更新版本。

如果您不在乎是否使用聚合,则可以在find()游标上进行迭代:

db.your_collection.find({}).forEach(
    function(doc) {    
        doc.content.recs = doc.content.recs.reduce((a, b) => a.concat(b), []);
        db.your_collection.save(doc);
    }
)

尽管这种方法的性能不如聚合,但有时会派上用场。例如,我更喜欢在使用Mongo Shell时使用这种方法,因为它的语法更容易记住,并且只允许我们处理需要更改的字段。在我的汇总示例中,如果您忘记在投影中添加一个字段,则文档将被保存而没有该字段。