87

使用代码:

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:数据库错误:运行器错误:溢出排序阶段缓冲数据使用量 33554495 字节超出内部限制 33554432 字节

我该如何处理?

4

6 回答 6

121

您在内存排序中遇到了 32MB 的限制:

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

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

于 2014-11-19T18:55:49.557 回答
47

正如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 }

我们还可以通过 mongodb 配置文件中的以下参数永久设置此限制:

setParameter=internalQueryExecMaxBlockingSortBytes=309715200

希望这可以帮助 !!!

Note:此命令仅在 3.0 + 版本后支持

于 2016-07-16T06:21:51.003 回答
25

用索引解决

db_handle.ensure_index([("reviewDate", pymongo.ASCENDING)])
于 2014-11-19T18:17:19.207 回答
15

如果您想避免创建索引(例如,您只想要一个快速而肮脏的检查来探索数据),您可以将聚合与磁盘使用情况一起使用:

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

(但不确定如何在 pymongo 中执行此操作)。

于 2017-06-23T12:50:30.737 回答
3

索引的 JavaScript API 语法:

db_handle.ensureIndex({executedDate: 1})
于 2018-03-20T12:58:37.107 回答
2

就我而言,有必要修复代码中的必要索引并重新创建它们:

rake db:mongoid:create_indexes RAILS_ENV=production

因为当有需要的字段索引时不会发生内存溢出。

PS在此之前,我必须在创建长索引时禁用错误:

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

也可能需要reIndex

# mongo
MongoDB shell version: 2.6.12
connecting to: test
> use your_db
switched to db your_db
> db.getCollectionNames().forEach( function(collection){ db[collection].reIndex() } )
于 2017-04-04T22:41:30.050 回答