我认为这确实是您正在处理的与 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
});