我的目标是更新itemSchema中每个对象的timeleft
字段。
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 :(得分:2)
查看您的用例我建议您修改问题的方法。显然,您正在创建具有“到期日期”的项目(或类似的东西,我将在下面使用“过期”一词)。到期时间为创建项目的24小时。
我不会将timeLeft
的值保存到数据库,而是在查询时动态重新计算。 (1)它是多余的,因为它可以从当前时间和time
值计算,据我所知,你的问题,(2)你必须不断更新timeleft
属性别扭。
您可以使用Mongoose的virtuals。
对Schema的更改,以确保在创建对象时返回虚拟内容:
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);
});
});
[edit]现在这是一个完整的演练,您应该能够复制和粘贴,而无需进行任何重大更改。