【问题标题】:MongoDB update nested item by dynamical IDMongoDB 通过动态 ID 更新嵌套项
【发布时间】:2017-01-08 18:06:42
【问题描述】:

嘿,我正在尝试更新我的 MongoDB 中的嵌套对象。

它们的结构是

[
 {
  "_id": "5871010d1ff9831574e7178d",
  "created_at": "2017-01-07T14:54:05.791Z",
  "updated_at": "2017-01-07T14:54:05.791Z",
  "place_id": "ChIJ1eTO6eS1vkcRL_mX2RWUKo4",
  "name": "Kunstwerk Restaurant Gummersbach",
  "__v": 0,
  "cooks": [],
  "menus": [
   {
    "58727068ba8d6c04a0ea331f": [
      {
        "intolerances": {
           "intolerance" : "false"
            ...
          },
        "nutritiondata" : [
          {...}
         ],
         "cookname": "testkoch@test.de",
         "menuname": "MenünameX"
      }
    ]
  }
]

menus 中的嵌套 ID 是动态创建的 MongoDB 文档的另一个 ID。

我尝试更新菜单名称,但无法访问它,因为 mongo 总是返回 null 或找不到元素,因为只需要搜索键而不是键值对。

到目前为止我测试了什么:

db.restaurants.update({ 'menus.58727068ba8d6c04a0ea331f', { $set : {"menus.$.menuname" : "test"}}});

db.restaurants.findOne({ 'menus.58727068ba8d6c04a0ea331f' : "58727068ba8d6c04a0ea331f"});

db.restaurants.find({ menus : { $elemMatch : {"58727068ba8d6c04a0ea331f": "58727068ba8d6c04a0ea331f" }}});

db.restaurants.findOne({ menus : { $eq : "58727068ba8d6c04a0ea331f" }});

【问题讨论】:

    标签: javascript mongodb mongoose mongo-shell


    【解决方案1】:

    使用$set方法如下图:

    db.restaurants.update({"_id":"5871010d1ff9831574e7178d"}, {$set: {"menus.58727068ba8d6c04a0ea331f.0.menuname":"test"});
    

    仅当您知道要更新的数组中的项目的索引时,这才有效。 检查这个Page,它有一些关于更新多层嵌套数组的好例子,希望它会有所帮助。

    【讨论】:

    • 感谢您的回复,所以我可以使用 $ 作为对象的占位符吗?作为示例菜单。"THE ID".$.menuname?同样在您的示例中,mongoshell 仅响应 ... 。所以那没用?
    • 它需要查询中的数组字段,您是否收到任何错误?
    • 不只是 3 点。我认为 auch 未决结果......但没有错误消息acures
    • 啊,我明白你的错误了。 “restaurants”拼写错误,缺少一个括号。现在有一条错误消息。 “在路径 'menus.$.58727068ba8d6c04a0ea331f.$.menuname 中找到太多位置(即 '$')元素”
    • 好的。您可以做的一件事是,如果您知道要更新的数组的索引,db.restaurents.update({"_id":"5871010d1ff9831574e7178d"}, {$set: {"menus.58727068ba8d6c04a0ea331f.0.menuname":"test"});
    【解决方案2】:

    感谢 suzo,我找到了解决方案。 有效的 MongoShell 代码:

    db.restaurants.update({"_id" : ObjectId("5871010d1ff9831574e7178d")}, {$set: {"menus.58727068ba8d6c04a0ea331f.0.menuname" : "testName"}});
    

    更新: 由于我的字段是混合类型,因此没有标记就不会更新!。所以这里是完整的正确代码:

     Restaurant.findOne({ _id : req.body.r_id }, function(error, restaurant){
        if(error) console.log(error);
    
        for(var i = 0; i < restaurant.menus.length; i++){
              restaurant.markModified('menus');
            if(restaurant.menus[i][req.params.id] != undefined){
                restaurant.menus[i][req.params.id].menuname = req.body.name;
            }
    
            if(i == restaurant.menus.length-1){
                restaurant.save();
                res.json(jObj);
            }
        }
    
      })
    

    【讨论】:

    • 酷。看起来和我的答案一样,但是我的问题是如果我们不知道数组的索引怎么办?
    • 更新了我的答案 :) 自从我想出我的第一个答案以来,一直遇到问题。所以我的解决方案是查看哪个键未定义。因为我只有唯一的键,所以这个方法有效。
    猜你喜欢
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 2020-10-22
    • 1970-01-01
    • 1970-01-01
    • 2016-04-01
    • 2013-09-05
    相关资源
    最近更新 更多