Mongoose caducan los datos pero se mantienen en la base de datos

Actualmente tengo datos guardados y caducando hacia / desde una base de datos a través de un esquema de mongoose como el siguiente:

var UserSchema = new Schema({ createdAt: { type: Date, expires: '1m' }, name: String, email: String }); 

El único problema es que el documento que se guarda en la base de datos se elimina completamente de la base de datos. ¿Cómo puedo refactorizar lo anterior para que el nombre / la dirección de correo electrónico permanezcan en la base de datos, pero si el usuario intenta iniciar sesión después de su fecha de caducidad, recibe un mensaje que dice “la sesión ha caducado, renueve la sesión”. (o algo similar)

Quiero hacerlo de esta manera porque entonces, si el usuario inicia sesión con una dirección de correo electrónico vencida, el servidor todavía puede buscar la dirección de correo electrónico y escupir un mensaje de “sesión expirada” en lugar de un error “no encontrado” que es Qué sucede cuando se borran los datos.

Entonces, para reiterar, ¿cómo mantengo los datos caducados en una base de datos mongo / mongoose para que la aplicación pueda encontrar la dirección de correo electrónico con la que el usuario intenta iniciar sesión pero si su sesión ha caducado, deben renovar la sesión?

Debe utilizar el concepto de referencia de esquema para esto. Guarde su campo caducado en otra tabla y únase a su tabla principal de user_table y expire_table (nombre de ejemplo)

 var UserSchema = new Schema({ name: String, email: String }); //save date by-default //expire in 1 min as in your example var expireSchema = new Schema({ createdAt: { type: Date, default: Date.now, expires: '1m' }, user_pk: { type: Schema.Types.ObjectId, ref: 'user_expire'} }); var userTable = mongoose.model('user_expire', UserSchema); var expireTable = mongoose.model('expireMe', expireSchema); //Save new user var newUser = new userTable({ name: 'my_name', email: 'my_email' }); newUser.save(function(err, result) { console.log(result, 'saved') var newExpire = new expireTable({ user_pk:result._id }); //use _id of new user and save it to expire table newExpire.save(function(err, result) { console.log('saved relation') }) }) 

Ahora para detectar si la sesión ha caducado o no

1. en la ejecución de este código antes de que caduquen los datos

 expireTable.findOne() .populate('user_pk') .exec(function (err, result) { if (err) throw err; console.log(result) if(result == null) { console.log('session has expired, renew session') } else { console.log('session is active') } }); //output - session is active 

2. en la ejecución de este código después de que los datos caducan

 expireTable.findOne() .populate('user_pk') .exec(function (err, result) { if (err) throw err; console.log(result) if(result == null) { console.log('session has expired, renew session') } else { console.log('session is active') } }); //output - session has expired, renew session 

La respuesta aceptada es buena, pero con Mongo 3.0 y superior, el

 createdAt: { type: Date, default: Date.now, expires: '1m' } 

no funciona para mi

En su lugar usé

 var expireSchema = new Schema({ expireAt: { type: Date, required: true, default: function() { // 60 seconds from now return new Date(Date.now() + 60000); } }, user_pk: { type: Schema.Types.ObjectId, ref: 'user_expire'} }); 

Más información está aquí: Tiempos de caducidad personalizados para documentos de mongoose en el nodo js

EDITAR

Mi comentario anterior también requeriría invocar una función Mongo directamente en lugar de a través de la syntax de Mongoose. Esto sería algo como:

  db.[collection-name].createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } ) 

Además, esto es para los documentos de caducidad a una hora específica del reloj de hacer un campo ttl.

Y parece que todavía no consigo que funcione, pero podría deberse a la forma errática en que se ejecuta el ttl reaper (una vez cada 60 segundos, pero podría ser más largo …)

EDITAR

Mis problemas se debieron a que un índice ttl configurado anteriormente de manera incorrecta persistía en el campo expireAt , lo que impedía que mi índice posterior (correctamente definido) funcionara. Arreglé esto simplemente eliminando cualquier índice anterior no _id y luego volviendo a agregar mi índice ttl en el campo expireAt .

Utilice db.[collection-name].getIndexes()

y

db.[collection-name].dropIndex({ "expireAt":1 }) para borrar antes de volver a aplicar.

También otra advertencia: establecer una instantánea de la Fecha en la propiedad predeterminada del campo expiredAt significa que el valor predeterminado siempre será una fecha fija; en lugar de eso, establezca este valor de la Fecha dinámicamente cada vez que cree una instancia de expireSchema :

 var expireSchema = new Schema({ expireAt: Date, user_pk: { type: Schema.Types.ObjectId, ref: 'user_expire' } }); expireSchema .virtual('expiryTime') .get(function() { //allow for reaper running at 60 second intervals to cause expireAt.fromNow message to be 'in the past' var expiryTime = moment(this.expireAt).fromNow(); if(String(expiryTime).indexOf("ago")){ expiryTime = "in a few seconds"; } return expiryTime; }); var expireModel = mongoose.model('UserExpire', expireSchema); expireModel.collection.ensureIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } );