我正在尝试在createdAt
和updatedAt
的{{1}}的子字段中添加otp
和generate: {}
时间戳
我知道使用verify:{}
会将{ 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}
答案 0 :(得分:4)
您必须为子字段定义一个单独的架构,然后将其用作子字段的类型。
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 });
答案 1 :(得分:2)
好吧,这个答案似乎变得越来越流行,因此a会扩展其覆盖范围。
{timesamps: true}
的工作方式以及工作方式?可从mongoose.js找到原始的{timesamps: true}
代码here @ line:1150
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();
});
因此,每次when mongoose driver triggers .save
on MongooseDocument都会执行此代码(当然,如果时间戳设置为true
)
MongooseDocument(对象)与js-Object / JSON / find({}).lean()
的结果之间有很大的区别
您可以在MongooseDocument上投放各种方法,例如.isNew
(这正是mongoose理解updatedAt
字段应该更新,而createdAt
不应更新的方式)。或将其转换为.toObject()
或.toJSON()
方法的完整列表可以为found here。
请确保:当您使用不带.find
选项的.lean()
时,您正在处理MongooseDocument,但是,如果启用它,您将收到纯JavaScript对象。
{timestamps: true}
的实现?通过default
值并在模式中使用setters
,很容易获得相同的结果:
createdAt: {type: Date, default: Date.now},
updatedAt: {type: Date, default: Date.now, set: v => v.Date.now()}
您可以阅读more about setters here。
也可以是您想要的任何函数,例如,您可以每次在任何插入||上修改值。修改操作(还有update
)
.. 或者您可以避免设置器,并每次通过以下方式手动更新代码中的
updatedAt
字段:每次model.findAndUpdate({your_field: value}, {your_field: value, updatedAt: Date.now())
。
因此,最后,使用setter(或手动查询更新)将为您提供与timestamps: true
选项相同的结果,但是您可以将其应用于架构中的每个子文档。
答案 2 :(得分:1)
我认为此类功能不属于要提供的数据库功能范围,也不属于启用猫鼬的功能。
您可能要创建另外两个具有 OneToMany 关系的实体Attribute
和AttributeValue
,以跟踪值的更改时间戳。
好吧,这就是我们在当前主要项目中解决问题的方式。
答案 3 :(得分:0)
我遇到了同样的问题,我的解决方案非常简单。
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
}