Mongodb更新深层嵌套的子文档

我有一个深度嵌套的文档结构,如下所示:

{id: 1, 
 forecasts: [ { 
             forecast_id: 123, 
             name: "Forecast 1", 
             levels: [ 
                { level: "proven", 
                  configs: [
                            { 
                              config: "Custom 1",
                              variables: [{ x: 1, y:2, z:3}]
                            }, 
                            { 
                              config: "Custom 2",
                              variables: [{ x: 10, y:20, z:30}]
                            }, 
                    ]
                }, 
                { level: "likely", 
                  configs: [
                            { 
                              config: "Custom 1",
                              variables: [{ x: 1, y:2, z:3}]
                            }, 
                            { 
                              config: "Custom 2",
                              variables: [{ x: 10, y:20, z:30}]
                            }, 
                    ]
                }
            ]
        }, 
    ]

}

我试图更新集合以插入一个新的配置,如下所示:

newdata =  {
  config: "Custom 1", 
  variables: [{ x: 111, y:2222, z:3333}]
}

我在mongo(Python中)尝试这样的东西:

db.myCollection.update({"id": 1, 
                        "forecasts.forecast-id": 123, 
                        "forecasts.levels.level": "proven", 
                        "forecasts.levels.configs.config": "Custom 1"
                         },
                         {"$set": {"forecasts.$.levels.$.configs.$": newData}}
                      )

虽然我得到了“不能应用位置运算符没有包含数组的相应查询字段”的错误。 在mongo中做这件事的正确方法是什么? 这是mongo v2.4.1。


不幸的是,每个键不能多次使用$运算符,因此您必须为其余的使用数字值。 如:

db.myCollection.update({
    "id": 1, 
    "forecasts.forecast-id": 123, 
    "forecasts.levels.level": "proven", 
    "forecasts.levels.configs.config": "Custom 1"
  },
  {"$set": {"forecasts.$.levels.0.configs.0": newData}}
)

MongoDB对更新嵌套数组的支持很差。 因此,如果您需要频繁更新数据,则最好避免使用它们,并考​​虑使用多个集合。

一种可能性:使forecasts自己的集合,假设你有一组固定的level值,使level的对象,而不是数组:

{
  _id: 123,
  parentId: 1,
  name: "Forecast 1", 
  levels: {
    proven: { 
      configs: [
        { 
          config: "Custom 1",
          variables: [{ x: 1, y:2, z:3}]
        }, 
        { 
          config: "Custom 2",
          variables: [{ x: 10, y:20, z:30}]
        }, 
      ]
    },
    likely: {
      configs: [
        { 
          config: "Custom 1",
          variables: [{ x: 1, y:2, z:3}]
        }, 
        { 
          config: "Custom 2",
          variables: [{ x: 10, y:20, z:30}]
        }, 
      ]
    }
  }
}

然后你可以使用以下方式更新它

db.myCollection.update({
    _id: 123,
    'levels.proven.configs.config': 'Custom 1'
  },
  { $set: { 'levels.proven.configs.$': newData }}
)

管理解决它与猫鼬使用:

所有你需要知道的是链中所有子文档的'_id'(mongoose为每个子文档自动创建'_id')。

例如 -

  SchemaName.findById(_id, function (e, data) {
      if (e) console.log(e);
      data.sub1.id(_id1).sub2.id(_id2).field = req.body.something;

      // or if you want to change more then one field -
      //=> var t = data.sub1.id(_id1).sub2.id(_id2);
      //=> t.field = req.body.something;

      data.save();
  });

有关猫鼬文档中的子文档_id方法的更多信息。

解释:_id用于SchemaName,_id1用于sub1,_id2用于sub2 - 可以像这样保持链接。

*您不必使用findById方法,但在我看来,这是最方便的,因为无论如何您都需要知道其余的_id。


这是MongoDB中的一个非常旧的错误

https://jira.mongodb.org/browse/SERVER-831

链接地址: http://www.djcxy.com/p/50233.html

上一篇: Mongodb update deeply nested subdocument

下一篇: How to list all collections in the mongo shell?