Existe-t-il un moyen d’ajouter des champs created_at et updated_at à un schéma mangouste sans devoir les transmettre à chaque fois que la nouvelle version de MyModel () est appelée?
Le champ created_at serait une date et n'a été ajouté que lorsqu'un document est créé. Le champ updated_at serait mis à jour avec la nouvelle date chaque fois que save () est appelé sur un document.
J'ai essayé ceci dans mon schéma, mais le champ ne s'affiche pas à moins que je l'ajoute expressément:
var ItemSchema = new Schema({
name : { type: String, required: true, trim: true }
, created_at : { type: Date, required: true, default: Date.now }
});
Si vous utilisez update()
ou findOneAndUpdate()
avec l'option {upsert: true}
vous pouvez utiliser $setOnInsert
var update = {
updatedAt: new Date(),
$setOnInsert: {
createdAt: new Date()
}
};
UPDATE: (5 ans plus tard)
Remarque: Si vous décidez d'utiliser Architecture Kappa ( Sourcing d'événement + CQRS ), alors vous n'avez pas du tout besoin de la date de mise à jour. Étant donné que vos données sont un journal d'événements immuable, comprenant uniquement les ajouts, vous avez uniquement besoin d'une date de création d'événement. Similaire à l'architecture Lambda , décrite ci-dessous. L'état de votre application est alors une projection du journal des événements (données dérivées). Si vous recevez un événement ultérieur concernant une entité existante, vous utiliserez la date de création de cet événement comme date de mise à jour pour votre entité. Ceci est une pratique couramment utilisée (et souvent mal comprise) dans les systèmes miceroservice.
UPDATE: (4 ans plus tard)
Si vous utilisez ObjectId
comme champ _id
(ce qui est généralement le cas), il vous suffit de:
let document = {
updatedAt: new Date(),
}
Vérifiez ma réponse originale ci-dessous sur la façon d'obtenir l'horodatage créé à partir du champ _id
. Si vous devez utiliser des identifiants d'un système externe, vérifiez la réponse de Roman Rhrn Nesterov.
UPDATE: (2,5 ans plus tard)
Vous pouvez maintenant utiliser l'option # timestamps avec la version Mongoose> = 4.0.
let ItemSchema = new Schema({
name: { type: String, required: true, trim: true }
},
{
timestamps: true
});
Si les horodatages sont définis, Mongoose affecte à votre schéma les champs createdAt
et updatedAt
, le type attribué à ce schéma est Date
.
Vous pouvez également spécifier les noms des fichiers timestamp:
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }
Remarque: Si vous travaillez sur une grosse application contenant des données critiques, vous devez reconsidérer la mise à jour de vos documents. Je vous conseillerais de travailler avec des données immuables, avec uniquement des ajouts ( architecture lambda ). Cela signifie que vous n'autorisez jamais que des insertions. Les mises à jour et les suppressions ne doivent pas être autorisées! Si vous souhaitez "supprimer" un enregistrement, vous pouvez facilement insérer une nouvelle version du document avec
timestamp
/version
a été classé puis défini dans un champdeleted
surtrue
. De même, si vous souhaitez mettre à jour un document, vous créez un nouveau avec les champs appropriés mis à jour et le reste des champs copié. Ensuite, pour interroger ce document, vous obtiendrez celui avec le timestamp le plus récent ou la version la plus élevée qui est pas "supprimé" (le champdeleted
n'est pas défini ou est faux`).L'immuabilité des données garantit que vos données sont déboguables - vous pouvez suivre l'historique de chaque document. Vous pouvez également revenir à la version précédente d'un document en cas de problème. Si vous optez pour une telle architecture,
ObjectId.getTimestamp()
est tout ce dont vous avez besoin, et cela ne dépend pas de Mongoose.
RÉPONSE ORIGINALE:
Si vous utilisez ObjectId comme champ d'identité, vous n'avez pas besoin du champ created_at
. ObjectIds a une méthode appelée getTimestamp()
.
ObjectId ("507c7f79bcf86cd7994f6c0e"). GetTimestamp ()
Cela retournera la sortie suivante:
ISODate ("2012-10-15T21: 26: 17Z")
Plus d'infos ici Comment extraire la date créée d'un ObjectID Mongo
Pour ajouter le fichier updated_at
, vous devez utiliser ceci:
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();
});
C'est ce que j'ai fini par faire:
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();
});
Utilisez l’option intégrée timestamps
pour votre schéma.
var ItemSchema = new Schema({
name: { type: String, required: true, trim: true }
},
{
timestamps: true
});
Cela ajoutera automatiquement les champs createdAt
et updatedAt
à votre schéma.
A partir de Mongoose 4.0, vous pouvez maintenant définir une option d'horodatage sur le schéma pour que Mongoose le gère pour vous:
var thingSchema = new Schema({..}, { timestamps: true });
Vous pouvez changer le nom des champs utilisés comme ceci:
var thingSchema = new Schema({..}, { timestamps: { createdAt: 'created_at' } });
Ajoutez timestamps
à votre Schema
comme ceci, puis createdAt
et updatedAt
générera automatiquement pour vous
var UserSchema = new Schema({
email: String,
views: { type: Number, default: 0 },
status: Boolean
}, { timestamps: {} });
Vous pouvez aussi changer createdAt -> created_at
en
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }
C'est comme ça que j'ai réussi à avoir créé et mis à jour.
Dans mon schéma, j'ai ajouté le créé et mis à jour comme suit:
/** * Schéma de l'article */ Var Schéma de l'article = new Schema ({ créé: { type: date, par défaut: date.à présent }, mis à jour: { type: date, default: Date.now }, titre: { type: Chaîne, par défaut: '', trim: true, requis: "Le titre ne peut être vide" }, contenu: { type: String, par défaut: '', trim: true }, utilisateur: { type: Schema.ObjectId, ref: 'Utilisateur' } });
Ensuite, dans ma méthode de mise à jour d'article à l'intérieur du contrôleur d'article, j'ai ajouté:
/** * Mettre à jour un article */ Exports.update = fonction (req, res) { Var article = req. article; article = _.extend (article, req.body); article.set ("updated", Date.now ()); article.save (fonction (err) { if (err) { renvoie le statut res (400) .send ({ message: errorHandler.getErrorMessage (err) }); } else { res.json (article); } }); };
Les sections en gras sont les parties d'intérêt.
var ItemSchema = new Schema({
name : { type: String, required: true, trim: true }
});
ItemSchema.set('timestamps', true); // this will add createdAt and updatedAt timestamps
Vous pouvez utiliser le plugin timestamp
de mongoose-troop
pour ajouter ce comportement à n’importe quel schéma.
Vous pouvez utiliser ce plugin très facilement. De la docs:
var timestamps = require('mongoose-timestamp');
var UserSchema = new Schema({
username: String
});
UserSchema.plugin(timestamps);
mongoose.model('User', UserSchema);
var User = mongoose.model('User', UserSchema)
Et définissez également le nom des champs si vous le souhaitez:
mongoose.plugin(timestamps, {
createdAt: 'created_at',
updatedAt: 'updated_at'
});
nous pouvons y parvenir en utilisant plugin de schéma également.
Dans le fichier 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);
};
et dans le fichier 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);
Ma version de mangouste est 4.10.2
Semble que le crochet findOneAndUpdate
est un travail
ModelSchema.pre('findOneAndUpdate', function(next) {
// console.log('pre findOneAndUpdate ....')
this.update({},{ $set: { updatedAt: new Date() } });
next()
})
Utilisez une fonction pour renvoyer la valeur par défaut calculée:
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();
});
Utilisez machinepack-datetime pour formater la date et l'heure.
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
});
Le pack machine est génial avec des API claires contrairement au monde Javascript, express ou général.
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 }
});
Maintenant, vous pouvez l'utiliser, de sorte qu'il n'est pas nécessaire d'inclure cette option dans chaque table
Je le fais réellement à l'arrière
Si tout se passe bien avec la mise à jour:
// 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
});
});