Mongodb 如何向mongoose模式子字段添加时间戳?
我试图在Mongodb 如何向mongoose模式子字段添加时间戳?,mongodb,mongoose,mongoose-schema,Mongodb,Mongoose,Mongoose Schema,我试图在generate:{}和verify:{}中的otp子字段中添加createdAt和updatedAt时间戳 我知道使用{timestamps:true}会将createdAt和updatedAt时间戳添加到整个模式中` const userSchema = new mongoose.Schema({ email: { type: String, unique: true }, name: { type: String }, mobileNumber:
generate:{}
和verify:{}
中的otp
子字段中添加createdAt
和updatedAt
时间戳
我知道使用{timestamps:true}
会将createdAt
和updatedAt
时间戳添加到整个模式中`
const userSchema = new mongoose.Schema({
email: { type: String, unique: true },
name: { type: String },
mobileNumber: {
isVerified: {type: Boolean, default: false},
otp: {
generate: {
attempts: {type: Number, default: 0},
total: {type: Number, default: 0},
createdAt: {type: Date},
updatedAt: {type: Date}
},
verify: {
attempts: {type: Number, default: 0},
total: {type: Number, default: 0},
createdAt: {type: Date},
updatedAt: {type: Date}
}
}
}
}, { timestamps: true });
向子字段添加单个时间戳的正确解决方案是什么?向子字段添加{timestamps:true}
是否正确
generate: {
attempts: {type: Number, default: 0},
total: {type: Number, default: 0},
{timestamps: true}
},
verify: {
attempts: {type: Number, default: 0},
total: {type: Number, default: 0},
{timestamps: true}
}
您必须为子字段定义单独的模式,然后将其用作子字段的类型
const otpSchema = new mongoose.Schema({
attempts: { type: Number, default: 0 },
total: { type: Number, default: 0 }
}, {
_id: false, // omit _id fields for subfields
timestamps: true // timestamps options for subfields
});
const userSchema = new mongoose.Schema({
email: { type: String, unique: true },
name: { type: String },
mobileNumber: {
isVerified: { type: Boolean, default: false },
otp: {
generate: otpSchema, // use the defined schema
verify: otpSchema
}
}
}, { timestamps: true });
好吧,这个答案似乎变得更受欢迎了,所以一份遗嘱将其扩展到了全覆盖范围
{timesamps:true}
做什么?它是如何做的?
可以找到mongoose.js中的原始{timesamps:true}
代码
如何准确地timestamps:true}
知道何时以及如何更新updatedAt
字段,而不更新createdAt
根据该守则:
this.pre('save', function(next) {
/**
* SKIP CODE A BIT
*/
if (!skipUpdatedAt && updatedAt && (this.isNew || this.isModified())) {
let ts = defaultTimestamp;
if (this.isNew) {
if (createdAt != null) {
ts = this.$__getValue(createdAt);
} else if (auto_id) {
ts = this._id.getTimestamp();
}
}
this.set(updatedAt, ts);
}
next();
});
因此,每次都会执行此代码(当然,如果时间戳设置为true
)
MongooseDocument(object)和js object/JSON/result offind({}).lean()之间有很大区别
您可以在MongooseDocument上强制转换各种方法,例如(这正是mongoose理解updatedAt
字段应该更新,而createdAt
不应该更新的方式)。或者将其转换为.toObject()
或.toJSON()
方法的完整列表
请确定:当您在不使用.lean()
选项的情况下使用.find
时,您正在处理MongooseDocument,但如果启用它,您将收到纯JavaScript对象
如何为自己的模式创建自己的{timestamps:true}
实现?
通过default
值和在模式中使用setters
可以轻松获得相同的结果:
createdAt: {type: Date, default: Date.now},
updatedAt: {type: Date, default: Date.now, set: v => v.Date.now()}
你可以阅读
此外,它可以是您想要的任何函数,例如,您可以每次在任何insert | | modify操作(以及update
)上修改值
..或者您可以避免设置器,每次都通过:model.findAndUpdate({your_字段:value},{your_字段:value,updatedAt:Date.now())手动更新代码中的updatedAt
字段
因此,最终,使用setter(或手动查询更新)将为您提供与timestamps:true
选项相同的结果,但您可以将其应用于模式中的每个子文档。我认为此类功能不属于要提供的数据库功能范围,也不属于要启用的mongoose
您可能需要创建另外两个实体-Attribute
和AttributeValue
与OneToMany关系,以跟踪值更改时间戳
嗯,这就是我们在我当前的主要项目中解决这个问题的方法。我遇到了同样的问题,我的解决方案非常简单
const userSchema = mongoose.Schema({ email: String }, { timestamps: true });
自动添加createdAt和updatedAt的我的结果:
{
"_id" : ObjectId("60ba2cb3bca3572f6ca1b525"),
"title" : "First post with timestamp",
"content" : "Test post timestamp",
"createdAt" : ISODate("2021-06-04T13:37:55.025Z"),
"updatedAt" : ISODate("2021-06-04T13:37:55.025Z"),
"__v" : 0
}
您好,如何通过$set
更新时间戳?我应该这样做吗?userSchema.pre('save',function(next){this.updatedAt=Date.now();return next();})
@TamashiKaizen为了避免误解,我更新了我的原始答案。你可以用你的更新查询更新字段updatedAt
,或者使用setters
来获得相同的结果。但是不修改你自己的查询。OP问题是针对子字段的:这种情况下有效吗?