Mongoose findOneAndUpdate Upsert _id null?

bin*_*ant 14 mongoose mongodb

我想要一个方法来创建或更新策略的文档.搜索并尝试像不同的技术这一块,我想出了一个空_id为我的文档.使用findByIdAndUpdate也有类似的影响.

我看到在集合中插入了一个文档,但_id字段为null:

exports.savePolicy = function (plcy, callback) {
    console.log('priority is : ' + plcy.priority)
    try {
        var policy = new Policy(plcy);
        var query = {_id: plcy._id};  //this may be null
        var update = {
            name: plcy.name || defaults.policyDefaults.name,
            longDescription: plcy.longDescription || defaults.policyDefaults.longDescription,
            shortDescription: plcy.shortDescription || defaults.policyDefaults.shortDescription,
            priority: plcy.priority, colorHex: plcy.colorHex || defaults.policyDefaults.colorHex,
            settings: plcy.settings || [],
            parentPolicyId: plcy.parentPolicyId || null
        }

        Policy.findOneAndUpdate(query, update, {upsert: true}, function (err, data) {
            callback(err, data);
        });

    } catch (e) {
        log.error('Exception while trying to save policy: ' + e.message);
        callback(e, null);
    }
Run Code Online (Sandbox Code Playgroud)

是否可以做一些事情来使_id不是一个不是更新时为空?

Joh*_*yHK 14

null_idMongoDB中的有效值,因此如果您不希望它在新文档中使用,则必须确保将null值替换为新ObjectIDquery:

var query = {_id: plcy._id};
if (!query._id) {
    query._id = new mongoose.mongo.ObjectID();
}

// the rest stays the same...
Run Code Online (Sandbox Code Playgroud)


Tre*_*ent 5

我有同样的问题,无法找到一种方法让它工作.我最后编写了自己的upsert方法....

var upsert = function(model, data, f){
  if (!data._id) {
    model.create(data, f);
  } else {
    var id = data._id;
    delete data._id;
    model.findOneAndUpdate({_id: id}, data, f);
  }
}
Run Code Online (Sandbox Code Playgroud)

这允许我用一行代码为我的任何模型调用它...

upsert(Team, team, f);
Run Code Online (Sandbox Code Playgroud)

可能有更好的方法,但这对我有用.我可以做更新和插入,我没有在插入时得到null _id.

  • 好吧,您可以使用以下方法解决此问题:Model.findOneAndUpdate({_id:id || Mongoose.Types.ObjectId()},{$ set:attrs},{upsert:true,new:true}) (2认同)

小智 5

如果有 ID,则更新文档;如果没有 ID,则创建新文档的最简单方法是:

Model.findOneAndUpdate({ _id: id ?? new mongoose.Types.ObjectId() }, updates, { upsert: true });

Run Code Online (Sandbox Code Playgroud)

请注意空合并运算符 (??)的使用,它允许 0 作为有效 id。该updates对象不需要包含id属性,因为 mongoose 会自动添加它

如果没有文档与过滤器匹配,MongoDB 将通过组合过滤器和更新来插入一个文档,如下所示。


Jef*_*sui -3

尝试在更新调用中将 upsert 参数设置为 true。来自 mongoid 文档:http://docs.mongodb.org/manual/reference/method/db.collection.update/#update-parameter

选修的。如果设置为 true,则在没有文档与查询条件匹配时创建新文档。默认值为 false,即未找到匹配项时不插入新文档。