2014-07-06 67 views
0

我現在有數據保存,並通過貓鼬模式從數據庫中到期而/像這樣:貓鼬到期數據,但保留在數據庫

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

唯一的問題是,所保存到數據庫中的文件是完全從數據庫中刪除。我將如何重構上述內容,以便姓名/電子郵件地址保留在數據庫中,但如果用戶在到期日期之後嘗試登錄,則會收到一條消息,指出「會話已過期,續訂會話」。 (或類似的東西)

我想這樣做,因爲如果用戶使用過期的電子郵件地址登錄,服務器仍然能夠查找電子郵件地址並吐出「過期會話」消息比數據被刪除時發生的「未找到」錯誤要多。

所以要重申,如何將過期的數據保存在mongo/mongoose數據庫中,以便應用程序能夠找到用戶嘗試登錄的電子郵件地址,但是如果他們的會話已過期,他們需要更新會話?

回答

3

您應該使用的概念架構參考爲此。保存另一個表中到期場並加入您的主要user_tableexpire_table(wxample名)

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 
0

接受的答案是好的,但與蒙戈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

編輯

我的評論上面也需要調用一個函數蒙哥,而不是直接通過貓鼬語法。這將是這樣的:

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

而且這是做一個TTL字段的Expire Documents at a Specific Clock Time方式。

而我仍然無法讓它工作,但可能是因爲ttl收割者運行的方式不穩定(每60秒一次,但可能會更長一些......))

EDIT

我的問題是由於具有較早配置不正確TTL索引堅持在expireAt領域,這防止了我後來的(正確定義)指數從工作。我通過刪除任何非_id較早的索引來解決這個問題,然後在expireAt字段上重新添加我的ttl索引。

使用db.[collection-name].getIndexes()

db.[collection-name].dropIndex({ "expireAt":1 })重新申請前清除。

而且另外一個警告 - 設置在expiredAt字段的默認屬性日期快照即表示默認值將始終是一個固定的日期 - 您創建的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 });