web-dev-qa-db-fra.com

ajouter des champs created_at et updated_at aux schémas mangouste

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 }
});
141
chovy

Si vous utilisez update() ou findOneAndUpdate()

avec l'option {upsert: true}

vous pouvez utiliser $setOnInsert

var update = {
  updatedAt: new Date(),
  $setOnInsert: {
    createdAt: new Date()
  }
};
28

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 champ deleted sur true. 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 champ deleted 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();
});
228
Pavel Nikolov

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();
});
130
chovy

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.

http://mongoosejs.com/docs/guide.html#timestamps

103
mcompeau

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' } });

http://mongoosejs.com/docs/guide.html#timestamps

72
Binarytales

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: {} });

enter image description here
Vous pouvez aussi changer createdAt -> created_at en

timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' }
24
Phan Van Linh

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.

8
rOOb85
var ItemSchema = new Schema({
    name : { type: String, required: true, trim: true }
});

ItemSchema.set('timestamps', true); // this will add createdAt and updatedAt timestamps

Docs: https://mongoosejs.com/docs/guide.html#timestamps

5
Nikolay_R

Vous pouvez utiliser le plugin timestamp de mongoose-troop pour ajouter ce comportement à n’importe quel schéma.

4
JohnnyHK

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'
});
3
Orr

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);
1
Shaishab Roy

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()
})
1
John Xiao

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();
});
0
orourkedd

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.

0
Piyush P
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

0
Raghu

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
      });
    });
0
shukar