将Update with Upsert设置为true时未设置默认值

我有以下模型的用户:

var UserSchema = new mongoose.Schema({ name: String, dob: Date, sex: String, photo: String, email: {type: String, index: {unique: true, required: true}}, created: {type: Date, default: Date.now} }); var User = mongoose.model('Users', UserSchema); 

正如你所看到的“创build”字段取当前date的默认值,以便在创build新用户时自动设置。

在发布用户详细信息时使用以下查询:

 User.findOneAndUpdate({email: user.email}, user, {upsert: true}, function (err, user) { if (err) { return callback (err); } else { callback(null, user); } }); 

upsert: true使用findOneAndUpdate的目的是要么返回一个现有的configuration文件,要么创build一个新的configuration文件。 它还根据发布的数据更新任何字段。

但是, created字段每次都会使用当前date进行更新,即使创build的字段未发布也是如此。 我怎样才能确保这个领域只设置一次?

编辑

数据库中的一个示例对象:

 { "_id" : ObjectId("54620b38b431d48bce7cab81"), "email" : "someone@google.com", "__v" : 0, "name" : "somone", "sex" : "male" } 

事实certificate,即使使用upsert创build新对象, created字段也没有被设置。 Mongoose只是返回基于模式的当前date,即使它不存在于文档中。

所以,现在的问题变成:如何确保使用upsert为参数中未提供的字段创build默认值?

findOneAndUpdate只发送一个MongoDB的findAndModify请求(见findOneAndUpdate )。 这意味着它跳过所有涉及模式设置器,获取器,默认等的mongoose魔法。validation只在创build/保存时运行,所以解决方法是做一个.findOne() ,检查存在/创build一个新的,然后.save()

看到这个问题更多的讨论

编辑:

关于每次更改date的第一个问题,您可以稍微更改一下模式。 摆脱默认值,而是声明模式之后添加:

 UserSchema.pre("save", function (next) { if (!this.created) { this.created = new Date(); } next(); }); 

如果created:值不存在,那么只会创build一个date,并且应该防止每次更改创builddate(使用.save() )。

看看Mongoose中间件