2017-01-13 108 views
0

我的目標是更新itemSchema中每個對象的timeleft字段。如何更新mongodb中的字段?

const ItemSchema = mongoose.Schema({ 
    name: String, 
    time: { type: Date, default: Date.now }, 
    timeleft: { type: Number, default: 24 } 
}); 

例如爲了讓我在ItemSchema

ItemSchema.methods.calculateTime = function() { // Done check it one hour 

    var currentTime = moment() // Get current Time 
    var timeStored = moment.utc(this.time).local().format(); // Convert this.time UTC to local time 
    var timeDiff = currentTime.diff(timeStored, 'h'); // See the difference in time example - 7 
    this.timeleft -= timeDiff; // Deduct timeleft witht he timeDiff , result would be 17 
    this.save(); // Simple save it to the database 
} 

API例如更新每個對象

app.get('/allItems', function(req, res) { 
    Item.find({}, function(err, items) { 
     // I want to run items.calculateTime(); but it is not possible. 
     // How would I run calculateTime function on the array of objects? 
    }); 
}); 

我的目標是繼續檢查的時間差,並把它保存到剩餘時間

數據示例

timeleft: 24 

// after calculateTime 
time: 17 

Because I want to show this to the User 

// 17 hours left 

我該如何做到這一點的對象數組,而不是單個對象?

+0

看看你的用例,我不會將這個值保存到數據庫中,而是在查詢時動態計算它。看看Mongoose的虛擬獲得者。 – qqilihq

+0

所以數據不會被保存到'timeleft'字段? – sinusGob

+0

是的。據我瞭解,它可以從'時間'屬性計算,對吧? – qqilihq

回答

2

看看你的用例,我會建議修改你的方法來解決這個問題。很明顯,你正在創建一個帶有「失效日期」的項目(或類似的東西,我將在下面使用術語「失效」)。該項目的創建時間爲24小時。

我不會保存價值爲timeLeft到數據庫,而是重新計算它在動態查詢。 (1)它是多餘的,因爲它可以從當前時間和價值計算,據我瞭解你的問題,(2)你將不得不更新timeleft財產連續看起來很尷尬。您可以使用貓鼬的virtuals

對架構更改,以確保,即虛函數返回創建對象時:

const ItemSchema = mongoose.Schema({ 
    name: String, 
    time: { type: Date, default: Date.now } 
}, { 
    // enable, to have the property available, 
    // when invoking toObject or toJSON 
    toJSON: { 
    virtuals: true 
    }, 
    toObject: { 
    virtuals: true 
    } 
}); 

定義虛擬財產timeLeft(我改變了代碼,而不moment工作):

// the virtual property, which is not stored in the DB, 
// but calculated after querying the database 
ItemSchema.virtual('timeLeft').get(function() { 
    var millisecondsDifference = Date.now() - this.time.getTime(); 
    var hoursDifference = millisecondsDifference/(1000 * 60 * 60); 
    return Math.max(0, 24 - hoursDifference); // cap to 24 hours 
}); 

您無法查詢虛擬屬性,因爲它們顯然不存在於數據庫中。相反,當您想要查詢已到達其過期日期的項目時,您可以搜索在過去24小時內創建的項目。爲了做到這一點方便,有代碼,在一個集中的地方,你可以將一個靜態方法來您的架構,它可以調用使用ItemModel.findNonExpired

// put the logic for querying non-expired items into 
// its own static function, which makes it easier to 
// reuse this functionality and understand what's going on 
ItemSchema.statics.findNonExpired = function(callback) { 
    return this.find({ 
    time: { 
     // find items which have a time within 
     // the last 24 hours 
     $gt: new Date(Date.now() - 1000 * 60 * 60 * 24) 
    } 
    }, callback); 
}; 
const ItemModel = mongoose.model('Item', ItemSchema); 

演示:

// create and save some some test items 
const items = [ 
    { name: 'created now' }, 
    { name: 'created an hour ago', time: new Date(Date.now() - 1000 * 60 * 60) }, 
    { name: 'created yesterday', time: new Date(Date.now() - 1000 * 60 * 60 * 24) }, 
    { name: 'created two days ago', time: new Date(Date.now() - 1000 * 60 * 60 * 24 * 2) }, 
]; 
ItemModel.create(items, function(err) { 
    if (err) throw err; 

    ItemModel.findNonExpired(function(err, items) { 
    if (err) throw err; 
    console.log(items); 
    }); 
}); 

[編輯]這是一個完整的演練,您應該能夠複製和粘貼而不需要任何重大更改。

+0

我編輯的問題,包括,將發現的所有項目的API。問題是我應該在哪裏放置'$ gt:new Date()'? – sinusGob

+0

和虛擬,我將如何設置'timeleft'爲24 ?,是單純'this.timeleft = 24'? – sinusGob

+0

我試着查詢,但好像它不返回'timeleft'財產。 – sinusGob

相關問題