我目前通过mongoose架构保存数据并从数据库过期,如下所示:
var UserSchema = new Schema({
createdAt: { type: Date, expires: '1m' },
name: String,
email: String
});
唯一的问题是保存到数据库的文档已从数据库中完全删除。我将如何重构上述内容,以便名称/电子邮件地址保留在数据库中,但如果用户在到期日后尝试登录,则他们会收到一条消息,说“会话已过期,续订会话”# 39 ;. (或类似的东西)
我想这样做,因为如果用户使用过期的电子邮件地址登录,服务器仍然可以查找电子邮件地址并吐出一个过期的会话"消息而不是"未找到"删除数据时发生的错误。
重申一下,如何将过期数据保存在mongo / mongoose数据库中,以便应用程序能够找到用户尝试登录的电子邮件地址,但如果他们的会话已过期,他们需要续订会话吗? / p>
答案 0 :(得分:5)
您应该使用架构参考的概念。将已过期字段保存在另一个表格中,然后加入主user_table
和expire_table
(例如名称)
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')
})
})
现在检测会话是否已过期
<强> 1。在数据过期之前执行此代码
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。在数据过期后执行此代码
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
答案 1 :(得分:0)
接受的答案很好,但是对于Mongo 3.0及以上版本,
createdAt: { type: Date, default: Date.now, expires: '1m' }
对我不起作用。
相反,我使用了
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'}
});
更多信息在这里:Custom expiry times for mongoose documents in node js
修改强>
我上面的评论还需要直接调用Mongo函数,而不是通过Mongoose语法。这将是:
db.[collection-name].createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )
此外,这是Expire Documents at a Specific Clock Time方式进行ttl字段。
我仍然无法让它发挥作用,但可能是因为ttl收割机运行的不稳定方式(每60秒一次,但可能更长......)
修改强>
我的问题是由于早先在expireAt
字段上保留了错误配置的ttl索引,这阻止了我以后(正确定义的)索引的工作。我修复此问题只是删除任何非_id早期索引,然后在expireAt
字段上重新添加我的ttl索引。
使用db.[collection-name].getIndexes()
和
db.[collection-name].dropIndex({ "expireAt":1 })
在重新申请之前清除。
另外另一个警告 - 在expiredAt
字段的默认属性中设置日期快照意味着默认值将始终是固定日期 - 而是在每次创建{的实例时动态设置此Date值{1}}:
expireSchema