如何更新mongodb中的字段?

时间:2017-01-13 14:12:24

标签: mongodb mongoose

我的目标是更新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

我如何对象数组而不是单个对象?

1 个答案:

答案 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]现在这是一个完整的演练,您应该能够复制和粘贴,而无需进行任何重大更改。