【问题标题】:Resample Time Data before Publishing to Client using Meteor.js在使用 Meteor.js 发布到客户端之前重新采样时间数据
【发布时间】:2014-08-25 06:29:53
【问题描述】:

一个集合data包含时间序列数据,例如

[
    { timestamp: 1404436523578, distance: 400 }, 
    { timestamp: 1404436525123, distance: 401 },
    { timestamp: 1404436578372, distance: 402 },
    { timestamp: 1404436382736, distance: 403 },
]

必须使用代表 10 分钟间隔的数据点来绘制此数据集。

与其向客户端发布一个巨大的数据集,然后在客户端浏览器上执行重采样,我们如何在发布重采样数据之前在服务器端对数据进行重采样?

是否有任何插件/包可以帮助重新采样时间序列数据?我只能找到one for Python

【问题讨论】:

  • 换种说法,听起来您想向客户端发送一个数据集,其中每个时间戳至少相隔 600000 毫秒(10 分钟), distance 值被平均/中位数,以便将省略的时间戳的数据合并到您正在发送的时间戳中。是的?如果很多客户端都接收到相同的数据,那么在最初保存数据时重新采样数据是值得的,也许是在一个单独的集合中;然后客户端只需订阅重新采样的集合,您就完成了。否则,您需要在通过Meteor.call 访问的服务器端方法中按需重新采样。

标签: javascript jquery node.js time meteor


【解决方案1】:

我认为这确实是您正在处理的与 mongo 相关的问题。 Meteor 不关心光标是什么样子,也不关心生成请求的文档集有多复杂。

Mongo 采样解决方案通常需要generating a new field which will be used explicitly for sample。在您的情况下,尽管 timestamp 看起来很适合这种用途。

所以我认为您需要做的就是在您的服务器上保留一组示例数据或示例时间戳。

生成样本:

var nextTimestamp = 0;
var sampleArray = [];
data.find({},{sort: {timestamp: 1}} ).forEach( doc ){
  if ( ! nextTimestamp || doc.timestamp > nextTimeStamp ){
    if ( ! nextTimestamp )
      nextTimestamp = doc.timestamp;
    else {
      while ( nextTimestamp < doc.timestamp ){
        nextTimestamp += 1000 * 60 * 10; //assumed timestamps are in milliseconds but step size can be whatever you need
      }
    }
    sampleArray.push( doc );
  }
}}; 

您可能希望在时间戳上有一个索引以加快排序。我通常会在创建集合后在下一行运行它。

data._ensureIndex( {timestamp: 1} );

这是否是一个好的解决方案取决于您在创建 sampleArray 后可以重复使用多少。因此,如果您的时间戳集合在客户端之间共享,请保存示例服务器端并将其用于多个客户端。如果同一个客户端重复使用相同的样本数据,则保存并重复使用。如果您需要使用新数据进行更新,请使用 $gt 查询来仅处理需要添加到示例中的数据点。

例如,您可以在返回 sampleArray 的发布函数中使用上述内容,并通过 observeChanges 使示例保持最新。

var handle data.find({timestamp: {$gt: nextTimestamp}}).observeChanges({
  added: function( id, doc ){
    //selector is not getting updated in the observeChanges so I think you need to keep checking timestamp
    if ( doc.timestamp > nextTimestamp ){
      while ( nextTimestamp < doc.timestamp ){
        nextTimestamp += 1000 * 60 * 10;
      }
      self.added( 'clientCollection', id, doc ) // self needs to be the thisObject of a publish 
    }
  });
});
self.onStop( function(){
  handle.stop();  // self needs to be the thisObject of a publish
});

【讨论】:

    【解决方案2】:

    您可以使用自定义发布。查看counts-by-room 示例。

    基本模式:

    服务器端

    Meteor.publish('resampledData', function() {
    
      var self = this;
    
      var data = getActualData();
      var resampledData = ABRACADABRA(data);
    
      _.each(resampledData, function(point){
        self.added('resampledData', point._id, point);
      });
    
      self.ready();
    
    });
    

    客户端

    ResampledData = new Meteor.Collection('resampledData');
    Meteor.subscribe('resampledData');
    

    当然,就像 Geoffrey 提到的那样,如果重新计算方法成本高且经常执行,那么将重新计算的数据存储在单独的集合中会更有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-11
      • 1970-01-01
      • 1970-01-01
      • 2012-06-24
      • 2021-10-31
      • 2014-01-20
      • 2014-12-15
      • 1970-01-01
      相关资源
      最近更新 更多