コードの使用:
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バイトを超えています
これをどのように処理しますか?
インメモリソートで32MBの制限に達しています:
https://docs.mongodb.com/manual/reference/limits/#Sort-Operations
ソートフィールドにインデックスを追加します。これにより、MongoDBは、ドキュメントをすべてサーバー上のメモリにロードしてメモリに並べ替えてからクライアントに送信するのではなく、並べ替えられた順序でドキュメントをストリーミングできます。
コメントセクションのkumar_harsh
で述べたように、別のポイントを追加したいと思います。
admin
データベースで以下のコマンドを使用して、現在のバッファー使用量を表示できます。
> use admin
switched to db admin
> db.runCommand( { getParameter : 1, "internalQueryExecMaxBlockingSortBytes" : 1 } )
{ "internalQueryExecMaxBlockingSortBytes" : 33554432, "ok" : 1 }
デフォルト値は2 MB(33554432バイト)です。この場合、バッファーデータが不足しているため、独自に定義した最適値でバッファー制限を増やすことができます。たとえば、次のように50 MBです。
> db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes:50151432})
{ "was" : 33554432, "ok" : 1 }
Mongodb構成ファイルの以下のパラメーターによって、この制限を永続的に設定することもできます。
setParameter=internalQueryExecMaxBlockingSortBytes=309715200
お役に立てれば !!!
Note
:このコマンドは、バージョン3.0以降でのみサポートされます+
インデックス付けで解決
db_handle.ensure_index([("reviewDate", pymongo.ASCENDING)])
インデックスの作成を避けたい場合(たとえば、データを探索するための迅速でダーティなチェックが必要な場合)、ディスク使用量のある集約を使用できます。
all_reviews = db_handle.aggregate([{$sort: {'reviewDate': 1}}], {allowDiskUse: true})
(しかし、pymongoでこれを行う方法はわかりません)。
インデックスのJavaScript API構文:
db_handle.ensureIndex({executedDate: 1})
私の場合、コード内のネサリーインデックスを修正して再作成する必要がありました。
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() } )