溢出sorting阶段缓冲的数据使用超过内部限制

使用代码:

all_reviews = db_handle.find().sort('reviewDate', pymongo.ASCENDING) print all_reviews.count() print all_reviews[0] print all_reviews[2000000] 

计数打印2043484 ,并打印all_reviews[0]

但是,当打印all_reviews[2000000] ,我得到的错误:

pymongo.errors.OperationFailure:数据库错误:运行器错误:溢出sorting阶段缓冲数据使用量33554495字节超过内部限制33554432字节

我该如何处理?

您正在运行内存中的32MB限制:

https://docs.mongodb.com/manual/reference/limits/#Sort-Operations

将索引添加到sorting字段。 这允许MongoDB以sorting顺序将文档stream式传输给您,而不是尝试将它们全部加载到服务器上的内存中,并在将它们发送到客户端之前将其sorting在内存中。

正如评论部分的kumar_harsh所说,我想补充一点。

您可以使用以下命令在admin数据库上查看当前的缓冲区使用情况:

 > use admin switched to db admin > db.runCommand( { getParameter : 1, "internalQueryExecMaxBlockingSortBytes" : 1 } ) { "internalQueryExecMaxBlockingSortBytes" : 33554432, "ok" : 1 } 

它有一个32 MB(33554432字节)的默认值。在这种情况下,您正在运行的缓冲区数据不足,因此您可以使用您自己定义的最佳值(例如50 MB)来增加缓冲区限制,如下所示:

 > db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes:50151432}) { "was" : 33554432, "ok" : 1 } 

希望这可以帮助 !!!

Note :这个命令只支持3.0 +以后的版本

用索引解决

 db_handle.ensure_index([("reviewDate", pymongo.ASCENDING)]) 

如果您想要避免创build索引(例如,您只需要快速检查数据),则可以使用磁盘使用情况下的聚合:

 all_reviews = db_handle.aggregate([{$sort: {'reviewDate': 1}}], {allowDiskUse: true}) 

(不知道如何做到这一点在pymongo,虽然)。

在我的情况下,有必要修复代码中的重要索引并重新创build它们:

 rake db:mongoid:create_indexes RAILS_ENV=production 

由于存在需要的字段索引时不会发生内存溢出。

PS在此之前,我不得不在创build长索引时禁用错误:

 # mongo MongoDB shell version: 2.6.12 connecting to: test > db.getSiblingDB('admin').runCommand( { setParameter: 1, failIndexKeyTooLong: false } )