Mongodb 猫鼬赢了';不要删除嵌入的文档

Mongodb 猫鼬赢了';不要删除嵌入的文档,mongodb,node.js,express,mongoose,Mongodb,Node.js,Express,Mongoose,我在这里摸不着头脑,就像通常的节点项目一样,我不确定我是做错了什么,还是遇到了错误 我有一个服务器模式,它可以有任意数量的被称为服务的嵌入式文档。我遇到了一个问题,尽管我已经成功地从服务器对象中删除了单个服务,但当我告诉它保存时,它并没有从数据库中删除它。save功能之所以能够工作,是因为它保存了我所做的任何更改,并且正在推送新的嵌入式文档,而不是删除已经存在的文档 下面是我的代码的一个相对简化的示例: app.put('/server/:id', function(req, res, next

我在这里摸不着头脑,就像通常的节点项目一样,我不确定我是做错了什么,还是遇到了错误

我有一个服务器模式,它可以有任意数量的被称为服务的嵌入式文档。我遇到了一个问题,尽管我已经成功地从服务器对象中删除了单个服务,但当我告诉它保存时,它并没有从数据库中删除它。save功能之所以能够工作,是因为它保存了我所做的任何更改,并且正在推送新的嵌入式文档,而不是删除已经存在的文档

下面是我的代码的一个相对简化的示例:

app.put('/server/:id', function(req, res, next){
  app.Server.findOne({_id: req.params.id}, function(err, server) {
    server.updated = new Date();
    ...

    for (var num = _.size(req.body.server.services) - 1; num >= 0; num--){
      // Is this a new service or an existing one
      if (server.services[num]) {
        // Is it marked for deletion? If so, delete it
        if (req.body.server.services[num].delete == "true") {
          server.services[num].remove()
        } else { // else, update it
          server.services[num].type = req.body.server.services[num].type
          ...
        }
      } else {
        // It's new, add it
        delete req.body.server.services[num]["delete"]
        server.services.push(req.body.server.services[num]);
      }
    }

    server.save(function(err){
      if (!err) {
        req.flash('success', 'Server updated')
      } else {
        req.flash('error', 'Err, Something broke when we tried to save your server. Sorry!')
        console.log(err)
      }
      res.redirect('/')
    });
  })
});
因此,remove()实际上是在删除服务。如果在保存之前执行server.toObject(),则它不在那里。你知道为什么它保存时不会从数据库中删除它吗


编辑:我想版本号会有帮助。node@0.4.2, mongoose@1.1.5 express@2.0.0rc

我找到了临时解决此问题的方法

我所做的是将嵌入的文档加载到一个数组中,拼接要删除的文档并替换该数组。大概是这样的:

var oldusers = dl.users;
oldusers.splice(dl.users.indexOf(req.currentUser.id), 1);
dl.users = oldusers;
dl.save(function(err) {...

我知道,根据文档的大小,我可能会错,因为我没有测试过您的示例,但这听起来好像Mongoose没有检测到嵌入的文档被修改了

从:

由于它是一种无模式类型,您可以将该值更改为您喜欢的任何其他值,但是Mongoose失去了自动检测/保存这些更改的能力。要“告诉”Mongoose混合类型的值已更改,调用文档的.markModified(path)方法,将路径传递给您刚刚更改的混合类型

person.anything = { x: [3, 4, { y: "changed" }] };
person.markModified('anything');
person.save(); // anything will now get saved

所以你的答案可能和使用markModified()函数一样简单。

我也有同样的问题。这将是完美的,除非markModified对儿童不起作用。见:在我的情况下工作。非常感谢你!Carlosedp的解决方案只在少数情况下对我有效。这种方法似乎在任何地方都有效,而且似乎是更“正确”的方法。谢谢这确实有效,但有人知道我们为什么要用它作为解决办法吗?