Mongoose过期数据但保留在数据库中

时间:2014-07-06 14:21:00

标签: node.js mongodb express mongoose

我目前通过mongoose架构保存数据并从数据库过期,如下所示:

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

唯一的问题是保存到数据库的文档已从数据库中完全删除。我将如何重构上述内容,以便名称/电子邮件地址保留在数据库中,但如果用户在到期日后尝试登录,则他们会收到一条消息,说“会话已过期,续订会话”# 39 ;. (或类似的东西)

我想这样做,因为如果用户使用过期的电子邮件地址登录,服务器仍然可以查找电子邮件地址并吐出一个过期的会话"消息而不是"未找到"删除数据时发生的错误。

重申一下,如何将过期数据保存在mongo / mongoose数据库中,以便应用程序能够找到用户尝试登录的电子邮件地址,但如果他们的会话已过期,他们需要续订会话吗? / p>

2 个答案:

答案 0 :(得分:5)

您应该使用架构参考的概念。将已过期字段保存在另一个表格中,然后加入主user_tableexpire_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