所以我基本上是在为我的代码开发一个时序模式;
var GameStatisticsSchema = new mongoose.Schema({
game: { type: mongoose.Schema.ObjectId, ref: 'Game', required: true }, 
months: [
  { // monthly viewers
      epoch: { type: Number, required: true }, // entry time stamp
      weeks: [
        { // weekly viewers
            epoch: { type: Number, required: true }, // entry time stamp
            days: [
              { // daily viewers
                  epoch: { type: Number, required: true }, // entry time stamp
                  hours: [
                    { // hourly viewers
                      epoch: { type: Number, required: true }, // entry time stamp
                      statistics: [
                        { // per minute statistics.
                            viewers: { type: Number },
                            channels: { type: Number },
                        }]
                  }]
            }]
      }]
}]
});基本上数据是存储为-因此我可以查询每天,每分钟,每周的数据,我喜欢;
{ 
"_id" : ObjectId("56a78e337a9a34f8a368f719"), 
"game" : ObjectId("56a6f0b5bbfbbad0550450ee"), 
"months" : {
    "1" : {
        "weeks" : {
            "5" : {
                "days" : {
                    "26" : {
                        "hours" : {
                            "17" : {
                                "statistics" : {
                                    "18" : {
                                        "channels" : NumberInt(46), 
                                        "viewers" : NumberInt(308)
                                    }
                                }, 
                                "epoch" : NumberInt(1453820400)
                            }
                        }, 
                        "epoch" : NumberInt(1453759200)
                    }
                }, 
                "epoch" : NumberInt(1453672800)
            }
        }, 
        "epoch" : NumberInt(1451599200)
    }
}, 
"__v" : NumberInt(0)
}基本上,我使用findOneAndUpdate()插入每分钟的传感器数据;
function updateStatistics(game, data) {
 return new Promise(function (resolve, reject) {
    // get current time
    var now = moment();
    var minute = now.minute();
    var hour = now.hour();
    var day = now.date();
    var week = now.week();
    var month = now.month() + 1; // moment months are 0 indexed
    // we'll store per hour, day, week and month subdocuments. so set the epochs for those.
    var update = {};
    update["months." + month + ".epoch"] = moment().startOf('month').unix();
    update["months." + month + ".weeks." + week + ".epoch"] = moment().startOf('isoWeek').unix();
    update["months." + month + ".weeks." + week + ".days." + day + ".epoch"] = moment().startOf('day').unix();
    update["months." + month + ".weeks." + week + ".days." + day + ".hours." + hour + ".epoch"] = moment().startOf('hour').unix();
    // set the viewers & channels.
    update["months." + month + ".weeks." + week + ".days." + day + ".hours." + hour + ".statistics." + minute + ".viewers"] =  data.viewers;
    update["months." + month + ".weeks." + week + ".days." + day + ".hours." + hour + ".statistics." + minute + ".channels"] =  data.channels;
    GameStatistics.findOneAndUpdate(
      { "game": game._id },
      { $set: update },
      {
          new: true, // return the updated document
          upsert: true, // create the document if does not exist
          runValidators: true,
          setDefaultsOnInsert: true
      },
      function(err, document) {
          if(err)
            reject(err);
          resolve();
      }
    );
  });
  }问题是,一旦我启用了;
runValidators: true,
setDefaultsOnInsert: true我的验证器将触发异常;
 Cannot update 'months.1.epoch' and 'months' at the same time因此,如果我禁用了runValidators,我可以这样存储数据,但是文档变得没有模式了--并且对此是唯一的;
var GameStatisticsSchema = new mongoose.Schema({
game: { type: mongoose.Schema.ObjectId, ref: 'Game', required: true }, 
months: [ { type: mongoose.Schema.Mixed }]});
那么你有什么建议的变通方法吗?
我使用支持翻转的findOneAndUpdate的原因是,如果没有它,我就不知道如何创建嵌套数组值和保存()文档。
请记住-对于26.01.2015 15:35:13,代码需要插入到this中;
months[1].weeks[5].days[26].hours[15].minutes[35].statistics.{
 viewers = 25;
 channels = 50
}发布于 2016-01-26 23:45:05
为什么不单独设置一个时间戳呢?
var GameStatisticsSchema = new mongoose.Schema({
    game: { type: mongoose.Schema.ObjectId, ref: 'Game', required: true  }, 
    timestamp: { type: DateTime },
    viewers: { type: Number },
    channels: { type: Number }
});这使得更新变得简单,您可以使用dateTime查询月份/日期/等。
上个月的查询将为:
{ game: gameId, timestamp: { $gt: <date from a month ago>}}但是你需要使用mongoose聚合函数,我对它不是很熟悉。
https://docs.mongodb.org/manual/reference/operator/aggregation/avg/
http://mongoosejs.com/docs/api.html#aggregate-js
https://stackoverflow.com/questions/35017511
复制相似问题