El uso de datos almacenados en buffer de etapa de clasificación de desbordamiento excede el límite interno

Usando el código:

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

El recuento imprime 2043484 e imprime all_reviews[0] .

Sin embargo, al imprimir all_reviews[2000000] , all_reviews[2000000] el error:

pymongo.errors.OperationFailure: error de base de datos: Error de Runner: el uso de datos almacenados en el buffer de la etapa de clasificación de overflow de 33554495 bytes excede el límite interno de 33554432 bytes

¿Cómo manejo esto?

Se está ejecutando en el límite de 32 MB en una ordenación en memoria:

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

Agregue un índice al campo de clasificación. Eso le permite a MongoDB transmitirle documentos en orden ordenado, en lugar de intentar cargarlos todos en la memoria del servidor y ordenarlos en la memoria antes de enviarlos al cliente.

Como dijo kumar_harsh en la sección de comentarios, me gustaría agregar otro punto.

Puede ver el uso del búfer actual utilizando el siguiente comando sobre la base de datos de admin :

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

Tiene un valor predeterminado de 32 MB (33554432 bytes) . En este caso, se está quedando corto de datos del búfer para que pueda boost el límite del búfer con su propio valor óptimo definido, por ejemplo, 50 MB como se muestra a continuación:

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

También podemos establecer este límite de forma permanente mediante el siguiente parámetro en el archivo de configuración de mongodb:

 setParameter=internalQueryExecMaxBlockingSortBytes=309715200 

Espero que esto ayude !!!

Note : Este comando solo es compatible después de la versión 3.0 +

resuelto con indexación

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

Si desea evitar la creación de un índice (p. Ej., Solo desea una comprobación rápida y sucia para explorar los datos), puede usar la agregación con el uso del disco:

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

(No estoy seguro de cómo hacer esto en Pymongo, sin embargo).

En mi caso, fue necesario corregir índices innecesarios en el código y recrearlos:

 rake db:mongoid:create_indexes RAILS_ENV=production 

Como el desbordamiento de memoria no ocurre cuando hay un índice de campo necesario.

PD Antes de esto tuve que deshabilitar los errores al crear índices largos:

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

La syntax de la API de JavaScript para el índice:

 db_handle.ensureIndex({executedDate: 1})