gpt4 book ai didi

javascript - MongoDB 查询大型集合

转载 作者:太空宇宙 更新时间:2023-11-03 22:34:08 24 4
gpt4 key购买 nike

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

该集合每 10 秒存储一次价格,但是当出于图表目的查询该集合时,每 1-2 分钟的价格非常重要。

我尝试用两种不同的方式编写此查询:

方法一:使用 {$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}}

如果我删除 sort('-timestamp") 行,并再次运行此查询,则会收到以下错误:

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

我还尝试在此查询中使用索引来尝试避免 32MB 内存排序限制,但未能成功。我想知道是否是由以下问题引起的:

"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'之前数据库中记录的最后一个价格。

编辑:方法 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 架构添加索引来使用索引:

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 秒。

关于javascript - MongoDB 查询大型集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32105567/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com