首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用mongoose更新嵌套数组

使用mongoose更新嵌套数组
EN

Stack Overflow用户
提问于 2016-01-26 23:28:53
回答 1查看 574关注 0票数 0

所以我基本上是在为我的代码开发一个时序模式;

代码语言:javascript
运行
复制
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 },
                        }]
                  }]
            }]
      }]
}]
});

基本上数据是存储为-因此我可以查询每天,每分钟,每周的数据,我喜欢;

代码语言:javascript
运行
复制
{ 
"_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()插入每分钟的传感器数据;

代码语言:javascript
运行
复制
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();
      }
    );
  });
  }

问题是,一旦我启用了;

代码语言:javascript
运行
复制
runValidators: true,
setDefaultsOnInsert: true

我的验证器将触发异常;

代码语言:javascript
运行
复制
 Cannot update 'months.1.epoch' and 'months' at the same time

因此,如果我禁用了runValidators,我可以这样存储数据,但是文档变得没有模式了--并且对此是唯一的;

代码语言:javascript
运行
复制
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中;

代码语言:javascript
运行
复制
months[1].weeks[5].days[26].hours[15].minutes[35].statistics.{
 viewers = 25;
 channels = 50
}
EN

回答 1

Stack Overflow用户

发布于 2016-01-26 23:45:05

为什么不单独设置一个时间戳呢?

代码语言:javascript
运行
复制
var GameStatisticsSchema = new mongoose.Schema({
    game: { type: mongoose.Schema.ObjectId, ref: 'Game', required: true  }, 
    timestamp: { type: DateTime },
    viewers: { type: Number },
    channels: { type: Number }
});

这使得更新变得简单,您可以使用dateTime查询月份/日期/等。

上个月的查询将为:

代码语言:javascript
运行
复制
{ 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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35017511

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档