Есть ли способ добавить поля created_at и updated_at в схему mongoose, без необходимости передавать их каждый раз, когда вызывается новый MyModel()?
Поле created_at будет датой и будет добавляться только при создании документа. Поле updated_at будет обновляться с новой датой, когда в документе вызывается функция save().
Я пробовал это в своей схеме, но поле не отображается, если я его не добавлю:
var ItemSchema = new Schema({
name : { type: String, required: true, trim: true }
, created_at : { type: Date, required: true, default: Date.now }
});
Если используется update()
или findOneAndUpdate()
с опцией {upsert: true}
вы можете использовать $setOnInsert
var update = {
updatedAt: new Date(),
$setOnInsert: {
createdAt: new Date()
}
};
ОБНОВЛЕНИЕ: (4 года спустя)
Если вы используете ObjectId
в качестве поля _id
(как правило, это так), все, что вам нужно сделать, это:
let document = {
updatedAt: new Date(),
}
Проверьте мой первоначальный ответ ниже, как получить созданную метку времени из поля _id
.
Если вам нужно использовать идентификаторы из внешней системы, ответьте на запрос Романа Ррнна Нестерова.
ОБНОВЛЕНИЕ: (2,5 года спустя)
Теперь вы можете использовать параметр #timestamps с версией mongoose >= 4.0.
let ItemSchema = new Schema({
name: { type: String, required: true, trim: true }
},
{
timestamps: true
});
Если установлены метки времени, mongoose присваивает вашим строкам поля createdAt
и updatedAt
, назначенный тип Date
.
Вы также можете указать имена имен меток:
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }
Примечание.. Если вы работаете над большим приложением с критическими данными, вы должны пересмотреть обновление своих документов. Я бы посоветовал вам работать с неизменяемыми, доступными только для приложения данными (лямбда-архитектура). Это означает, что что вы только разрешаете вставки. Обновления и удаления не должны быть разрешено! Если вы хотите "удалить" запись, вы можете легко вставьте новую версию документа с помощью
timestamp
/version
и затем установите для поляdeleted
значениеtrue
. Аналогично, если вы хотите для обновления документа - вы создаете новый с соответствующим поля обновлены, а остальные поля скопированы. Затем, чтобы запросите этот документ, вы получите тот, у которого установлена самая новая отметка времени или самая высокая версия, которая не "удалена" (полеdeleted
undefined или false`).Непрерывность данных гарантирует, что ваши данные отлаживаются - вы можете отслеживать история каждого документа. Вы также можете откат к предыдущему версию документа, если что-то пойдет не так. Если вы идете с таким архитектура
ObjectId.getTimestamp()
- это все, что вам нужно, и это не Зависит от Мангуста.
ОРИГИНАЛЬНЫЙ ОТВЕТ:
Если вы используете ObjectId в качестве поля идентификации, вам не нужно поле created_at
. ObjectIds имеют метод под названием getTimestamp()
.
ObjectId("507c7f79bcf86cd7994f6c0e").getTimestamp()
Это вернет следующий вывод:
ISODate("2012-10-15T21:26:17Z")
Подробнее здесь Как извлечь созданную дату из объекта Mongo ObjectID
Чтобы добавить updated_at
, вам необходимо использовать это:
var ArticleSchema = new Schema({
updated_at: { type: Date }
// rest of the fields go here
});
ArticleSchema.pre('save', function(next) {
this.updated_at = Date.now();
next();
});
Вот что я сделал:
var ItemSchema = new Schema({
name : { type: String, required: true, trim: true }
, created_at : { type: Date }
, updated_at : { type: Date }
});
ItemSchema.pre('save', function(next){
now = new Date();
this.updated_at = now;
if ( !this.created_at ) {
this.created_at = now;
}
next();
});
getTimestamp()
Используйте встроенную опцию timestamps
для вашей схемы.
var ItemSchema = new Schema({
name: { type: String, required: true, trim: true }
},
{
timestamps: true
});
Это автоматически добавит поля createdAt
и updatedAt
к вашей схеме.
Начиная с Mongoose 4.0 теперь вы можете установить параметр timestamps на Схеме, чтобы Mongoose справился с этим для вас:
var thingSchema = new Schema({..}, { timestamps: true });
Вы можете изменить имя полей, используемых так:
var thingSchema = new Schema({..}, { timestamps: { createdAt: 'created_at' } });
Вот как я добился создания и обновления.
Внутри моей схемы я добавил созданный и обновленный так:
/** * Article Schema */ var ArticleSchema = new Schema({ created: { type: Date, default: Date.now }, updated: { type: Date, default: Date.now }, title: { type: String, default: '', trim: true, required: 'Title cannot be blank' }, content: { type: String, default: '', trim: true }, user: { type: Schema.ObjectId, ref: 'User' } });
Затем в моей статье метод обновления внутри контроллера статьи я добавил:
/** * Update a article */ exports.update = function(req, res) { var article = req.article; article = _.extend(article, req.body); article.set("updated", Date.now()); article.save(function(err) { if (err) { return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); } else { res.json(article); } }); };
Облачные области представляют интерес.
Добавьте timestamps
к вашему Schema
, как это, тогда createdAt
и updatedAt
автоматически сгенерируют для вас
var UserSchema = new Schema({
email: String,
views: { type: Number, default: 0 },
status: Boolean
}, { timestamps: {} });
Также вы можете изменить createdAt -> created_at
на
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }
Вы можете использовать плагин timestamp
mongoose-troop
, чтобы добавить это поведение в любую схему.
Вы можете легко использовать этот плагин. Из документов:
var timestamps = require('mongoose-timestamp');
var UserSchema = new Schema({
username: String
});
UserSchema.plugin(timestamps);
mongoose.model('User', UserSchema);
var User = mongoose.model('User', UserSchema)
И также задайте имя полей, если хотите:
mongoose.plugin(timestamps, {
createdAt: 'created_at',
updatedAt: 'updated_at'
});
Использовать machinepack-datetime для форматирования даты и времени.
tutorialSchema.virtual('createdOn').get(function () {
const DateTime = require('machinepack-datetime');
let timeAgoString = "";
try {
timeAgoString = DateTime.timeFrom({
toWhen: DateTime.parse({
datetime: this.createdAt
}).execSync(),
fromWhen: new Date().getTime()
}).execSync();
} catch(err) {
console.log('error getting createdon', err);
}
return timeAgoString; // a second ago
});
Машинный пакет отлично справляется с понятным API, в отличие от обычного или общего Javascript-мира.
Я действительно делаю это в спине
Если все будет хорошо с обновлением:
// All ifs passed successfully. Moving on the Model.save
Model.lastUpdated = Date.now(); // <------ Now!
Model.save(function (err, result) {
if (err) {
return res.status(500).json({
title: 'An error occured',
error: err
});
}
res.status(200).json({
message: 'Model Updated',
obj: result
});
});
Моя версия мангуста - 4.10.2
Кажется, что работает только hook findOneAndUpdate
ModelSchema.pre('findOneAndUpdate', function(next) {
// console.log('pre findOneAndUpdate ....')
this.update({},{ $set: { updatedAt: new Date() } });
next()
})
const mongoose = require('mongoose');
const config = require('config');
const util = require('util');
const Schema = mongoose.Schema;
const BaseSchema = function(obj, options) {
if (typeof(options) == 'undefined') {
options = {};
}
if (typeof(options['timestamps']) == 'undefined') {
options['timestamps'] = true;
}
Schema.apply(this, [obj, options]);
};
util.inherits(BaseSchema, Schema);
var testSchema = new BaseSchema({
jsonObject: { type: Object }
, stringVar : { type: String }
});
Теперь вы можете использовать это, так что нет необходимости включать эту опцию в каждую таблицу
мы можем достичь этого, используя плагин схемы.
В helpers/schemaPlugin.js
файле
module.exports = function(schema) {
var updateDate = function(next){
var self = this;
self.updated_at = new Date();
if ( !self.created_at ) {
self.created_at = now;
}
next()
};
// update date for bellow 4 methods
schema.pre('save', updateDate)
.pre('update', updateDate)
.pre('findOneAndUpdate', updateDate)
.pre('findByIdAndUpdate', updateDate);
};
и в models/ItemSchema.js
файле:
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
SchemaPlugin = require('../helpers/schemaPlugin');
var ItemSchema = new Schema({
name : { type: String, required: true, trim: true },
created_at : { type: Date },
updated_at : { type: Date }
});
ItemSchema.plugin(SchemaPlugin);
module.exports = mongoose.model('Item', ItemSchema);
Используйте функцию для возврата вычисленного значения по умолчанию:
var ItemSchema = new Schema({
name: {
type: String,
required: true,
trim: true
},
created_at: {
type: Date,
default: function(){
return Date.now();
}
},
updated_at: {
type: Date,
default: function(){
return Date.now();
}
}
});
ItemSchema.pre('save', function(done) {
this.updated_at = Date.now();
done();
});
Date.now()
в функцию, просто сделайте: ...default: Date.now()
Вы можете использовать middleware и virtuals. Ниже приведен пример вашего поля updated_at
:
ItemSchema.virtual('name').set(function (name) {
this.updated_at = Date.now;
return name;
});
name
. И да, это должно быть постоянным.