Node.js Mongoose model.save()未按预期工作

Node.js Mongoose model.save()未按预期工作,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我有此代码,在我尝试保存新文档后,MongoDB正在传回一个错误: var data = { _id: '55d65cfde9cf73322361860b' // _id is a string here }; var model = new Model(data); model.save(function (err, result) { if (err) { done(err); //the error

我有此代码,在我尝试保存新文档后,MongoDB正在传回一个错误:

   var data = {
       _id: '55d65cfde9cf73322361860b'  // _id is a string here
    };

   var model = new Model(data);

    model.save(function (err, result) {
        if (err) {
            done(err);  //the error is captured here in my code
        }
        else{
            done(null, result);
        }
    });
我得到一个错误:

MongoError: E11000 duplicate key error index: dev_local_db_smartconnect.jobs.$_id_ dup key: { : ObjectId('55d65cfde9cf73322361860b') }
但是,我的印象是,如果模型/文档存在,save将更新它(通过使用隐式upsert=true选项),并且它将使用_id字段查找现有文档

有人知道为什么会发生这种错误吗

另一方面,这对我很有用:

where data is the new data for the model, and _id is a string not an ObjectID, and Model is the mongoose class, not the instance.

 Model.update({_id:_id}, {$set: data}, {upsert:true} , function(err,result){
                if (err) {
                    done(err);
                }
                else if (result) {
                    done(null, result);
                }
                else {
                    done(new Error('grave error'));
                }
        });

由于您正在创建一个新的本地文档,Mongoose不知道它已经存在于服务器上,因此它将尝试将其保存为新文档。然后,Mongo将拒绝该文档,因为具有该ID的现有文档已经存在

如果先查询该文档,然后保存返回的文档,它将按预期工作。大概是这样的:

Model.find({id: '55d65cfde9cf73322361860b'}, function (err, doc) {
  // update doc with something
  // ...

  doc.save(function (err, result) {
    if (err) {
      done(err);  //the error is captured here in my code
    }
    else {
      done(null, result);
    }
  });
});

谢谢Jason,这应该行得通,我只想避免两次DB呼叫。我认为有很多人不认为有必要从数据库中检索文档,然后进行更新,需要第二次数据库调用。在我提供的第二个示例中(碰巧工作正常),它应该在不增加额外成本的情况下(TMK)通过一个DB调用来完成所有事情。@AlexMills,以避免您可以使用各种
findAndModify
方法(例如
findAndUpdate
FindEndUpdate
FindByAndUpdate
,等等)。使用它们的主要问题是跳过文档的任何模式验证,因为它直接通过Mongo修改文档。您也可以使用
Model.update()
,但同样的问题也适用。是的,我听说了,我只需要看看这是否会成为问题。对于put和post,中间件和验证可能非常有用,但是对于get和deletes,可能可以绕过它。