当前位置: 首页 > 知识库问答 >
问题:

MongoDB查询大集合

终彬郁
2023-03-14

我有一个名为“Prices”的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}}

如果删除排序('-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(),我也尝试过使用。流()。

 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); 
 });

任何帮助将不胜感激!

共有1个答案

公冶和豫
2023-03-14

我算是想通了。

我设法通过向猫鼬模式添加索引来使索引工作:

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

 类似资料:
  • 我正在使用reactive mongodb开发简单的spring webflux演示应用程序,我想按姓名读取员工的所有数据,但不包括姓名字段“joe”、“Sara”、“joe”、“Sara”,我有如下代码: //仓库接口 //服务类

  • 我使用Nodejs和MongoDB与expressjs和mongoose库,创建一个具有用户、文章和评论模式的博客API。下面是我使用的模式。

  • 主要内容:aggregate() 方法,管道MongoDB 中的聚合操作用来处理数据并返回计算结果,聚合操作可以将多个文档中的值组合在一起,并可对数据执行各种操作,以返回单个结果,有点类似于 SQL 语句中的 count(*)、group by 等。 aggregate() 方法 您可以使用 MongoDB 中的 aggregate() 方法来执行聚合操作,其语法格式如下: db.collection_name.aggregate(aggr

  • 问题内容: 我有一个博客系统,可将上传的文件存储到GridFS系统中。问题是,我不知道如何查询它! 我将Mongoose与尚未支持GridFS的NodeJS一起使用,因此我将实际的mongodb模块用于GridFS操作。没有SEEM可以像常规集合中的文档一样查询文件元数据。 将元数据存储在指向GridFS objectId的文档中是否明智?可以轻松查询? 任何帮助将不胜感激,我有点卡住了:/ 问题

  • 我在MongoDB中有以下表单的集合。正如您所看到的,有些文档有两个成员“id”和“xid”,而有些文档只有1个“id”(除了对象_id之外) 我想创建一个mongoexport语句,它将ID和xid值都>0的文档导出到仅csv的文档

  • 例如,我在MongoDB中有以下数据: 现在我想查询“SUM传入的数量在11 - 12之间”(结果应该是500),我如何使用Mongo Shell来做到这一点?