Timestamps时间戳
Mongoose schemas support a Mongoose模式支持timestamps option. timestamps选项。If you set 如果您设置timestamps: true, Mongoose will add two properties of type Date to your schema:timestamps: true,Mongoose将向您的模式中添加两个Date类型的属性:
createdAt: a date representing when this document was created:表示创建此文档的日期updatedAt: a date representing when this document was last updated:表示此文档上次更新的日期
Mongoose will then set 然后,Mongoose将在首次插入文档时设置createdAt when the document is first inserted, and update updatedAt whenever you update the document using save(), updateOne(), updateMany(), findOneAndUpdate(), update(), replaceOne(), or bulkWrite().createdAt,并在使用save()、updateOne()、updateMany()、findOneAndUpdate()、update()、replaceOne()或bulkWrite()更新文档时更新updatedAt。
const userSchema = new Schema({ name: String }, { timestamps: true });
const User = mongoose.model('User', userSchema);
let doc = await User.create({ name: 'test' });
console.log(doc.createdAt); // 2022-02-26T16:37:48.244Z
console.log(doc.updatedAt); // 2022-02-26T16:37:48.244Z
doc.name = 'test2';
await doc.save();
console.log(doc.createdAt); // 2022-02-26T16:37:48.244Z
console.log(doc.updatedAt); // 2022-02-26T16:37:48.307Z
doc = await User.findOneAndUpdate({ _id: doc._id }, { name: 'test3' }, { new: true });
console.log(doc.createdAt); // 2022-02-26T16:37:48.244Z
console.log(doc.updatedAt); // 2022-02-26T16:37:48.366Z
The createdAt property is immutable, and Mongoose overwrites any user-specified updates to updatedAt by default.createdAt属性是不可变的,默认情况下Mongoose会将任何用户指定的更新覆盖到updatedAt。
let doc = await User.create({ name: 'test' });
console.log(doc.createdAt); // 2022-02-26T17:08:13.930Z
console.log(doc.updatedAt); // 2022-02-26T17:08:13.930Z
doc.name = 'test2';
doc.createdAt = new Date(0);
doc.updatedAt = new Date(0);
await doc.save();
// Mongoose blocked changing `createdAt` and set its own `updatedAt`, ignoring
// the attempt to manually set them.
console.log(doc.createdAt); // 2022-02-26T17:08:13.930Z
console.log(doc.updatedAt); // 2022-02-26T17:08:13.991Z
// Mongoose also blocks changing `createdAt` and sets its own `updatedAt`
// on `findOneAndUpdate()`, `updateMany()`, and other query operations
doc = await User.findOneAndUpdate(
{ _id: doc._id },
{ name: 'test3', createdAt: new Date(0), updatedAt: new Date(0) },
{ new: true }
);
console.log(doc.createdAt); // 2022-02-26T17:08:13.930Z
console.log(doc.updatedAt); // 2022-02-26T17:08:14.008Z
Alternate Property Names备用属性名称
For the purposes of these docs, we'll always refer to 出于这些文档的目的,我们将始终引用createdAt and updatedAt. But you can overwrite these property names as shown below.createdAt和updatedAt。但是您可以覆盖这些属性名称,如下所示。
const userSchema = new Schema({ name: String }, {
timestamps: {
createdAt: 'created_at', // Use `created_at` to store the created date
updatedAt: 'updated_at' // and `updated_at` to store the last updated date
}
});
Disabling Timestamps禁用时间戳
save(), updateOne(), updateMany(), findOneAndUpdate(), update(), replaceOne(), and bulkWrite() all support a timestamps option. save()、updateOne()、updateMany()、findOneAndUpdate()、update()、replaceOne()和bulkWrite()都支持timestamps选项。Set 设置timestamps: false to skip setting timestamps for that particular operation.timestamps: false可跳过为该特定操作设置时间戳。
let doc = await User.create({ name: 'test' });
console.log(doc.createdAt); // 2022-02-26T23:28:54.264Z
console.log(doc.updatedAt); // 2022-02-26T23:28:54.264Z
doc.name = 'test2';
// Setting `timestamps: false` tells Mongoose to skip updating `updatedAt` on this `save()`
await doc.save({ timestamps: false });
console.log(doc.updatedAt); // 2022-02-26T23:28:54.264Z
// Similarly, setting `timestamps: false` on a query tells Mongoose to skip updating
// `updatedAt`.
doc = await User.findOneAndUpdate({ _id: doc._id }, { name: 'test3' }, {
new: true,
timestamps: false
});
console.log(doc.updatedAt); // 2022-02-26T23:28:54.264Z
// Below is how you can disable timestamps on a `bulkWrite()`
await User.bulkWrite([{
updateOne: {
filter: { _id: doc._id },
update: { name: 'test4' },
timestamps: false
}
}]);
doc = await User.findOne({ _id: doc._id });
console.log(doc.updatedAt); // 2022-02-26T23:28:54.264Z
You can also set the 您还可以将timestamps option to an object to configure createdAt and updatedAt separately. timestamps选项设置为一个对象,以分别配置createdAt和updatedAt。For example, in the below code, Mongoose sets 例如,在下面的代码中,Mongoose在createdAt on save() but skips updatedAt.save()上设置createdAt,但跳过updatedAt。
const doc = new User({ name: 'test' });
// Tell Mongoose to set `createdAt`, but skip `updatedAt`.
await doc.save({ timestamps: { createdAt: true, updatedAt: false } });
console.log(doc.createdAt); // 2022-02-26T23:32:12.478Z
console.log(doc.updatedAt); // undefined
Disabling timestamps also lets you set timestamps yourself. 禁用时间戳还可以让您自己设置时间戳。For example, suppose you need to correct a document's 例如,假设您需要更正文档的createdAt or updatedAt property. createdAt或updatedAt属性。You can do that by setting 您可以通过设置timestamps: false and setting createdAt yourself as shown below.timestamps: false并设置createdAt自己来完成,如下所示。
let doc = await User.create({ name: 'test' });
// To update `updatedAt`, do a `findOneAndUpdate()` with `timestamps: false` and
// `updatedAt` set to the value you want
doc = await User.findOneAndUpdate({ _id: doc._id }, { updatedAt: new Date(0) }, {
new: true,
timestamps: false
});
console.log(doc.updatedAt); // 1970-01-01T00:00:00.000Z
// To update `createdAt`, you also need to set `strict: false` because `createdAt`
// is immutable
doc = await User.findOneAndUpdate({ _id: doc._id }, { createdAt: new Date(0) }, {
new: true,
timestamps: false,
strict: false
});
console.log(doc.createdAt); // 1970-01-01T00:00:00.000Z
Timestamps on Subdocuments子文档上的时间戳
Mongoose also supports setting timestamps on subdocuments. Mongoose还支持在子文档上设置时间戳。Keep in mind that 请记住,子文档的createdAt and updatedAt for subdocuments represent when the subdocument was created or updated, not the top level document. Overwriting a subdocument will also overwrite createdAt.createdAt和updatedAt表示子文档的创建或更新时间,而不是顶级文档。覆盖子文档也会覆盖createdAt。
const roleSchema = new Schema({ value: String }, { timestamps: true });
const userSchema = new Schema({ name: String, roles: [roleSchema] });
const doc = await User.create({ name: 'test', roles: [{ value: 'admin' }] });
console.log(doc.roles[0].createdAt); // 2022-02-27T00:22:53.836Z
console.log(doc.roles[0].updatedAt); // 2022-02-27T00:22:53.836Z
// Overwriting the subdocument also overwrites `createdAt` and `updatedAt`
doc.roles[0] = { value: 'root' };
await doc.save();
console.log(doc.roles[0].createdAt); // 2022-02-27T00:22:53.902Z
console.log(doc.roles[0].updatedAt); // 2022-02-27T00:22:53.902Z
// But updating the subdocument preserves `createdAt` and updates `updatedAt`
doc.roles[0].value = 'admin';
await doc.save();
console.log(doc.roles[0].createdAt); // 2022-02-27T00:22:53.902Z
console.log(doc.roles[0].updatedAt); // 2022-02-27T00:22:53.909Z
Under the Hood引擎盖下
For queries with timestamps, Mongoose adds 2 properties to each update query:对于带有时间戳的查询,Mongoose为每个更新查询添加2个属性:
Add将updatedAtto$setupdatedAt添加到$setAdd将createdAtto$setOnInsertcreatedAt添加到$setOnInsert
For example, if you run the below code:例如,如果您运行以下代码:
mongoose.set('debug', true);
const userSchema = new Schema({
name: String
}, { timestamps: true });
const User = mongoose.model('User', userSchema);
await User.findOneAndUpdate({}, { name: 'test' });
You'll see the below output from Mongoose debug mode:您将看到以下来自Mongoose调试模式的输出:
Mongoose: users.findOneAndUpdate({}, { '$setOnInsert': { createdAt: new Date("Sun, 27 Feb 2022 00:26:27 GMT") }, '$set': { updatedAt: new Date("Sun, 27 Feb 2022 00:26:27 GMT"), name: 'test' }}, {...})
Notice the 注意$setOnInsert for createdAt and $set for updatedAt. createdAt的$setOnInsert和updatedAt的$set。MongoDB's MongoDB的$setOnInsert operator applies the update only if a new document is upserted. $setOnInsert运算符仅在新文档被upserted时应用更新。So, for example, if you want to only set 因此,例如,如果您想在创建新文档时仅在文档中设置updatedAt if the document if a new document is created, you can disable the updatedAt timestamp and set it yourself as shown below:updatedAt,则可以禁用updatedAt时间戳并自行设置,如下所示:
await User.findOneAndUpdate({}, { $setOnInsert: { updatedAt: new Date() } }, {
timestamps: { createdAt: true, updatedAt: false }
});
