tutorial nodejs node example español node.js mongodb express mongoose

node.js - nodejs - agregue los campos created_at y updated_at a los mongoose schemas



node js express mongodb rest api (16)

¿Hay alguna forma de agregar los campos created_at y updated_at a un esquema de mangosta, sin tener que pasarlos cada vez que se llame a MyModel () nuevo?

El campo created_at sería una fecha y solo se agregará cuando se cree un documento. El campo updated_at se actualizará con una nueva fecha siempre que se llame a save () en un documento.

He intentado esto en mi esquema, pero el campo no aparece a menos que lo agregue explícitamente:

var ItemSchema = new Schema({ name : { type: String, required: true, trim: true } , created_at : { type: Date, required: true, default: Date.now } });


A partir de Mongoose 4.0, ahora puede establecer una opción de marcas de tiempo en el esquema para que Mongoose maneje esto por usted:

var thingSchema = new Schema({..}, { timestamps: true });

Puede cambiar el nombre de los campos usados ​​así:

var thingSchema = new Schema({..}, { timestamps: { createdAt: ''created_at'' } });

#timestamps


Agregue timestamps de timestamps a su Schema esta manera, luego createdAt y updatedAt . updatedAt automáticamente para usted

var UserSchema = new Schema({ email: String, views: { type: Number, default: 0 }, status: Boolean }, { timestamps: {} });


También puede cambiar createdAt -> created_at por

timestamps: { createdAt: ''created_at'', updatedAt: ''updated_at'' }


Así es como logré haber creado y actualizado.

Dentro de mi esquema agregué el creado y actualizado así:

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

Luego, en el método de actualización de mi artículo dentro del controlador del artículo, agregué:

/** * 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); } }); };

Las secciones en negrita son las partes de interés.


De hecho, hago esto en la parte posterior

Si todo va bien con la actualización:

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


Esto es lo que terminé haciendo:

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


Mi versión de mangosta es 4.10.2

Parece que solo el gancho findOneAndUpdate es trabajo

ModelSchema.pre(''findOneAndUpdate'', function(next) { // console.log(''pre findOneAndUpdate ....'') this.update({},{ $set: { updatedAt: new Date() } }); next() })


Puede usar middleware y virtuals . Aquí hay un ejemplo para su campo updated_at :

ItemSchema.virtual(''name'').set(function (name) { this.updated_at = Date.now; return name; });


Puede usar el plugin timestamp de mongoose-troop para agregar este comportamiento a cualquier esquema.


Puedes usar este plugin muy fácilmente. De los documentos:

var timestamps = require(''mongoose-timestamp''); var UserSchema = new Schema({ username: String }); UserSchema.plugin(timestamps); mongoose.model(''User'', UserSchema); var User = mongoose.model(''User'', UserSchema)

Y también establezca el nombre de los campos si lo desea:

mongoose.plugin(timestamps, { createdAt: ''created_at'', updatedAt: ''updated_at'' });


Si usa update() o findOneAndUpdate()

con la {upsert: true}

puedes usar $setOnInsert

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


Use la opción integrada de timestamps de timestamps para su esquema.

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

Esto agregará automáticamente los campos createdAt y updatedAt a su esquema.

#timestamps


Use machinepack-datetime para formatear la fecha y hora.

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

El paquete de la máquina es excelente, con una API clara a diferencia del mundo expreso o general de Javascript.


Use una función para devolver el valor predeterminado calculado:

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


podemos lograr esto usando también el complemento de esquema .

En el archivo 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); };

y en el archivo 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);


ACTUALIZACIÓN: (5 años después)

Nota: Si decide usar Kappa Architecture ( Event Sourcing + CQRS ), entonces no necesita actualizar la fecha. Como sus datos son un registro de eventos inmutables y de solo anexar, solo necesita la fecha de creación del evento. Similar a la arquitectura Lambda , que se describe a continuación. Luego, su estado de aplicación es una proyección del registro de eventos (datos derivados). Si recibe un evento posterior sobre la entidad existente, usará la fecha creada de ese evento como fecha actualizada para su entidad. Esta es una práctica comúnmente utilizada (y comúnmente incomprendida) en sistemas de miceroservicio.

ACTUALIZACIÓN: (4 años después)

Si usa ObjectId como su campo _id (que generalmente es el caso), entonces todo lo que necesita hacer es:

let document = { updatedAt: new Date(), }

Verifique mi respuesta original a continuación sobre cómo obtener la marca de tiempo creada del campo _id . Si necesita usar IDs del sistema externo, entonces verifique la respuesta de Roman Rhrn Nesterov.

ACTUALIZACIÓN: (2.5 años después)

Ahora puede usar la opción #timestamps con mongoose version> = 4.0.

let ItemSchema = new Schema({ name: { type: String, required: true, trim: true } }, { timestamps: true });

Si se establecen marcas de tiempo, mongoose asigna los campos createdAt y updatedAt a su esquema, el tipo asignado es Date .

También puede especificar los nombres de los archivos de la marca de tiempo:

timestamps: { createdAt: ''created_at'', updatedAt: ''updated_at'' }

Nota: Si está trabajando en una gran aplicación con datos críticos, debería reconsiderar la actualización de sus documentos. Te aconsejo que trabajes con datos inmutables y de solo unir ( arquitectura lambda ). Lo que esto significa es que solo permites inserciones. ¡Las actualizaciones y eliminaciones no deberían ser permitidas! Si desea "eliminar" un registro, puede insertar fácilmente una nueva versión del documento con alguna timestamp / version archivada y luego establecer un campo deleted en true . De manera similar, si desea actualizar un documento, cree uno nuevo con los campos apropiados actualizados y el resto de los campos copiados. Luego, para consultar este documento, obtendrá el que tenga la marca de tiempo más reciente o la versión más alta que sea no "eliminado" (el campo deleted es indefinido o falso`).

La inmutabilidad de los datos asegura que sus datos sean depurables; puede rastrear el historial de cada documento. También puede retroceder a la versión anterior de un documento si algo sale mal. Si ObjectId.getTimestamp() una arquitectura de este tipo, ObjectId.getTimestamp() es todo lo que necesita y no depende de Mongoose.

RESPUESTA ORIGINAL:

Si está utilizando ObjectId como su campo de identidad, no necesita el campo created_at . Los objetos tienen un método llamado getTimestamp() .

ObjectId("507c7f79bcf86cd7994f6c0e").getTimestamp()

Esto devolverá el siguiente resultado:

ISODate("2012-10-15T21:26:17Z")

Más información aquí ¿Cómo extraigo la fecha de creación de un Mongo ObjectID

Para agregar updated_at filed, necesitas usar esto:

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


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

Ahora puede usar esto, de modo que no es necesario incluir esta opción en todas las tablas