如何更新mongodb中的字段? [英] How do i update a field in mongodb?
问题描述
我的目标是更新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
该如何处理对象数组而不是单个对象?
看看您的用例,我建议您修改解决该问题的方法.显然,您正在创建带有到期日期"的项目(或类似的内容,在下文中,我将使用术语已到期").有效期为创建商品的24小时.
我不会将的值保存到数据库,而是在查询时动态地重新计算. (1)冗余,因为可以根据当前时间和 您可以使用Mongoose的参考. 更改架构以确保在创建对象时返回了虚拟物: 定义虚拟属性 您无法查询虚拟属性,因为它们显然不存在于数据库中.相反,当您要查询已过期的商品时,可以搜索在过去24小时内创建的商品.为了方便地执行该操作并将该代码放在一个中央位置,您可以将静态方法附加到您的模式,可以使用time
值来计算,据我了解的问题,(2)您必须连续更新timeleft
属性,这似乎很麻烦.>
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
});
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]现在,这是完整的演练,您应该可以在不进行较大更改的情况下复制和粘贴.
My goal is to update timeleft
field on every object in the itemSchema.
const ItemSchema = mongoose.Schema({
name: String,
time: { type: Date, default: Date.now },
timeleft: { type: Number, default: 24 }
});
For example in order for me to update every object in the 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 example
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?
});
});
My goal is to keep checking the time difference and save it to the time left
Data example
timeleft: 24
// after calculateTime
time: 17
Because I want to show this to the User
// 17 hours left
How would I do this to array of objects, instead of single object?
Looking at your use case I would suggest to modify your approach to the problem. Obviously you're creating items with an "expiry date" (or something similar, I'll be using the term "expired" in the following). The expiry is 24 hours from the time where the item was created.
I would not save the value for timeLeft
to the DB, but rather recalculate it dynamically upon querying. (1) It's redundant, as it can be calculated from the current time and the time
value, as far as I understood your question, (2) you would have to update the timeleft
property continuously which seems awkward.
You can make use of Mongoose's virtuals.
Changes to the Schema to make sure, that the virtuals are returned when creating objects:
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
}
});
Define the virtual property timeLeft
(I changed the code to work without 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
});
You cannot query on virtual properties, because they obviously do not exist in the database. Instead, when you want to query for items which have reached their expiry date, you can search for items which have been created within the last 24 hours. In order to do that conveniently and have that code at a central place, you can attach a static method to your schema, which you can call using 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);
Demo:
// 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] This is now a full walkthrough, which you should be able to copy and paste without requiring any big changes.
这篇关于如何更新mongodb中的字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!