Mongoose findOneAndUpdate和upsert返回没有错误,没有文档受到影响

mik*_*ana 21 javascript mongoose mongodb node.js

我有一个非常小的模型:

var CompanySchema = new mongoose.Schema({
    name: { type: String, required: true, unique: true },
});

var Company = mongoose.model('Company', CompanySchema)
Run Code Online (Sandbox Code Playgroud)

我试图添加单个文档,如果它不存在.目前,我测试时没有文件:

models.Company.findOneAndUpdate({
    name: 'companyName'
}, {upsert: true}, function(err, numberAffected, raw){
    console.log(err, numberAffected, raw)
})
Run Code Online (Sandbox Code Playgroud)

这是使用Mongoose文档中upsert选项

然而err就是null,numberAffected为空.为什么我的文件没有更新?

Ray*_*jax 28

从Mongoose 4+开始,不要忘记设置new:true和upsert,否则您将获得旧文档作为返回值,而不是更新的值.

这非常棘手,特别是当请求创建文档时,就像您没有指定new:true,您收到一个空文档(没有现有文档),但没有错误.

    var myObj = ...;
    collection.findOneAndUpdate(
    {uniqueAttr: myObj.uniqueAttr},
    myObj,
    {upsert: true, new: true},
    function(...) {...}
Run Code Online (Sandbox Code Playgroud)

  • 你救了我的一天!在迁移到最新版本的mongoose之后,我正在敲打我的脑袋 (3认同)

小智 25

在您的代码中,您使用的是方法的3参数版本,findOneAndUpdate因此,根据您发布的文档,参数为:A.findOneAndUpdate(conditions, update, callback).

您应该使用方法的第4个参数版本来指定upsert选项.

我想指出我从来没有使用过框架猫鼬.希望这可以帮助.

编辑:是的,在您的情况下,conditions并且update是相同的.如果您的对象比示例中显示的对象更复杂,您可能需要检查_id或"唯一"(不受MongoDB保证)属性(如果它有索引,则更好).例如:

var myObj = ...;
collection.findOneAndUpdate({uniqueAttr: myObj.uniqueAttr}, myObj, {upsert: true}, function(){
     ...
});
Run Code Online (Sandbox Code Playgroud)

  • 这有点奇怪:我希望简单地创建一个文件,如果它不存在,所以`conditions`和`update`是相同的,但这确实解决了问题. (5认同)