MongoDB查询大集合

我有一个名为“价格”的MongoDB集合,我试图查询“startDate”和“endDate”之间的价格。

该系列产品每隔10秒钟就会储存一次价格,但是当查询这个系列产品时,每1-2分钟价格就非常重要。

我试图用两种不同的方式来写这个查询:

方法1:使用{$ gte:startDate,$ lte:endDate}

function getResultsInRange(startDate, endDate) { if(typeof startDate !== 'undefined' && typeof endDate !== 'undefined') { Price.find({timestamp: {$gte: startDate, $lte: endDate}}, 'price timestamp exchange') .sort('-timestamp') // .populate('exchange') .exec(function(err, prices) { if(err) { res.jsonp({'error': err}); } else { console.log("Found: " + prices.length + " prices"); res.jsonp(prices); } }); } } 

此方法引发以下错误:

 {"error":{"name":"MongoError","$err":"Executor error: Overflow sort stage buffered data usage of 33554490 bytes exceeds internal limit of 33554432 bytes","code":17144}} 

如果我删除sorting(' – timestamp“)行,并再次运行此查询,我得到以下错误:

 GET /prices/graph/minute - - ms - - FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory 

我也尝试过在这个查询中使用索引来试图避免32MB的内存sorting限制,但一直没有能够实现。 我想知道是否是由这个问题引起的:

 "The total size of an index entry, which can include structural overhead depending on the BSON type, must be less than 1024 bytes." 

这里描述:( http://docs.mongodb.org/manual/reference/limits/#indexes )

方法2:使用While循环来查询每个X分钟的最后价格(例如2)

 function getResultsInRange(startDate, endDate) { if(typeof startDate !== 'undefined' && typeof endDate !== 'undefined') { var currentDate = startDate; currentDate.setSeconds(0); var priceData = {}; while(currentDate < endDate) { Price.findOne({'timestamp': {$lte: currentDate}}, 'price timestamp exchange') .sort('-timestamp') .exec(function(err, price) { if(err) { console.log('ERROR: ' + err); } else if (price !== null) { // PUSH DATA TO ARRAY HERE } }); // Increment Current Date. currentDate.setMinutes(currentDate.getMinutes() + 2); } res.jsonp(priceData); }//end if startDate and endDate are defined (giving us a valid date range). }// end getResultsInRange() 

然而,这种方法不起作用,对于循环currentDate'='startDate'的每一次迭代,似乎只是在'startdate'之前查询数据库中logging的最后一个价格。

编辑:方法3:使用stream()我也尝试使用.stream()。

  var query = Price.find({timestamp: {$gte: startDate, $lte: endDate}}, 'price timestamp exchange').populate('exchange').stream(); query.on('data', function(price) { // ADD TO ARRAY }).on('error', function(err) { console.log("ERROR: " + err); }).on('close', function() { res.jsonp(priceData); }); 

任何帮助将非常感激!

我明白了这一点。

我设法通过向Mongoose Schema添加一个索引来处理索引:

 timestamp: { type: Date, index: true, default: Date.now }, 

然后使用下面的函数来执行查询。

 function getResultsInRange(startDate, endDate) { if(typeof startDate !== 'undefined' && typeof endDate !== 'undefined') { Price.find({timestamp: {$gte: startDate, $lte: endDate}}, 'price timestamp exchange') .sort('-timestamp') .populate('exchange') .exec(function(err, prices) { if(err) { res.jsonp({'error': err}); } else { res.jsonp(prices); } }); } } 

以上的工作可以在startDate和endDate之间达到14天的范围,即使索引运行也需要大约20秒的时间。