ZeM*_*oon 4 mongoose mongodb node.js mongodb-update
我为用户提供以下模型:
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);
Run Code Online (Sandbox Code Playgroud)
如您所见,“创建”字段采用当前日期的默认值,以便在创建新用户时自动设置该日期。
发布用户详细信息时,我使用以下查询:
User.findOneAndUpdate({email: user.email}, user, {upsert: true}, function (err, user) {
if (err) {
return callback (err);
} else {
callback(null, user);
}
});
Run Code Online (Sandbox Code Playgroud)
使用findOneAndUpdatewith 的目的upsert: true是返回一个现有的配置文件,或创建一个新的配置文件。它还根据发布的数据更新所有字段。
但是,created即使未发布创建的字段,该字段也会每次都使用当前日期进行更新。如何确保仅将该字段设置一次?
编辑
数据库中的示例对象:
{
"_id" : ObjectId("54620b38b431d48bce7cab81"),
"email" : "someone@google.com",
"__v" : 0,
"name" : "somone",
"sex" : "male"
}
Run Code Online (Sandbox Code Playgroud)
事实证明,created即使在使用upsert创建新对象时也未设置该字段。猫鼬仅根据架构返回当前日期,即使该日期在文档中不存在。
因此,现在的问题变成了:如何确保使用using upsert为参数中未提供的字段创建默认值?
findOneAndUpdate只需发送一个 MongoDBfindAndModify请求(请参阅findOneAndUpdate)。这意味着它跳过了与模式设置器、获取器、默认值等相关的所有猫鼬魔法。验证仅在创建/保存时运行,因此解决此问题的方法是执行 a .findOne(),检查存在/创建一个新的,然后然后.save()。
编辑:
关于每次更改日期的第一个问题,您可以稍微更改架构。摆脱默认值,并在声明架构后添加此值:
UserSchema.pre("save", function (next) {
if (!this.created) {
this.created = new Date();
}
next();
});
Run Code Online (Sandbox Code Playgroud)
仅当该值不存在时才会创建日期created:,并且应防止每次更改创建日期(使用时.save())。
参见 Mongoose 中间件
如果将默认值添加到文档中(如果它是使用findOneAndUpdate创建的(在查询之前不存在),并且未在更新中提供该字段),则应使用setDefaultsOnInsert。
当upsert和setDefaultsOnInsert均为true时,如果找不到该记录并创建一个新记录,则将设置默认值。这跳过了必须检查记录是否存在以及是否不存在,然后仅通过确保设置了默认值而使用“保存”创建新记录的工作流程。
我遇到了同样的问题(使用findOneAndUpdate创建的具有upsert的记录:true),并且字段的默认值没有添加到记录中,即使它在模式中也是如此。这仅是在使用findOneAndUpdate创建文档时添加默认值,而不是为了跳过“ created”字段的更新。
即User.findOneAndUpdate({email:user.email},user,{upsert:true,setDefaultsOnInsert:true},...)
| 归档时间: |
|
| 查看次数: |
3477 次 |
| 最近记录: |