Mongoose upsert 不创建默认模式属性

Posted

技术标签:

【中文标题】Mongoose upsert 不创建默认模式属性【英文标题】:Mongoose upsert does not create default schema property 【发布时间】:2014-11-03 12:26:05 【问题描述】:

示例文档架构:

var CompanySchema = Schema(
    created:  type: Date, default: Date.now ,
    modified:  type: Date, default: Date.now ,
    address:  type: String, required:true ,
    name:  type: String, required:true 
);

我正在使用通用请求处理程序来编辑和创建“公司”文档:

exports.upsert = function(req, res) 
    helper.sanitizeObject(req.body);
    var company = 
        name: req.body.name,
        address: req.body.address
    ;
    var id = req.body.id || new mongoose.Types.ObjectId();
    var queryOptions = 
        upsert: true
    ;
    Company.findByIdAndUpdate(id, company, queryOptions).exec(function(error, result) 
        if(!error) 
            helper.respondWithData(req, res, 
                data: result.toJSON()
            );
         else 
            helper.respondWithError(req, res, helper.getORMError(error));
        
    );
;

但是使用这种方法,当插入新文档时,createdmodified 属性不会保存为默认值Date.now。现在我可以根据 id 的存在调用Company.create,但我想知道如果新文档上不存在属性,为什么 upsert 不使用默认值?

我正在使用 Mongoose 版本 ~3.8.10,

【问题讨论】:

【参考方案1】:

发生的情况是,在调用任何“更新”系列方法(如 findByIdAndUpdate)时,没有使用 Mongoose 的验证、中间件或默认值。它们只能通过调用savecreate 来调用。

原因是“更新”调用实际上是对本机驱动程序的传递,Mongoose 仅​​提供基于模式定义的字段类型转换。

Mongoose 4.0 更新

Mongoose 现在支持在 updatefindOneAndUpdatefindByIdAndUpdate upsert 期间创建新文档时设置默认值。将setDefaultsOnInsert 选项设置为true 以启用此功能。这使用$setOnInsert 运算符在插入时创建默认值。

var queryOptions = 
    upsert: true,
    setDefaultsOnInsert: true
;
Company.findByIdAndUpdate(id, company, queryOptions).exec( ...

【讨论】:

【参考方案2】:

您可以使用 "$setOnInsert": value: 31 Doc

参考:https://groups.google.com/forum/#!topic/mongoose-orm/WuJSqxPX8T8

语法:findOneAndUpdate([query], [doc], [options], [callback])Doc

示例:

model.findOneAndUpdate(
       username: 'john' ,
       "$setOnInsert":  points: '0' ,
            $push: 
            "boards": 
                "account":req.body.account,
                "game":req.body.game                                        
            
                  
       upsert: true,
      function(err, doc)     

      );

【讨论】:

谢谢,我不知道! 最好设置选项upsert: true, setDefaultsOnInsert: true,而不是为每个findOneAndUpdate 调用重新列出相同的默认值。 See JohnnyHK's answer to this qestion. 叹息我一直在琢磨为什么 setDefaultOnInsert 不起作用,最后发现我拼错了。 setDefault s OnInsert。我完全错过了。

以上是关于Mongoose upsert 不创建默认模式属性的主要内容,如果未能解决你的问题,请参考以下文章

runValidator 属性无法在 mongodb 上使用 mongoose 进行 upsert

(mongoose/promises) 如何检查文档是不是是使用 findOneAndUpdate 和 upsert 创建的

Mongoose upsert 重复键错误

Mongodb/Mongoose bulkwrite(upsert) 性能问题

Mongoose upsert ?????????

带有 upsert 的 Mongoose 重复键错误