pymongo.errors.CursorNotFound: el ID del cursor ‘…’ no es válido en el servidor

Estoy intentando obtener algunos ID que existen en una base de datos de Mongo con el siguiente código:

client = MongoClient('xx.xx.xx.xx', xxx) db = client.test_database db = client['...'] collection = db.test_collection collection = db["..."] for cursor in collection.find({ "$and" : [{ "followers" : { "$gt" : 2000 } }, { "followers" : { "$lt" : 3000 } }, { "list_followers" : { "$exists" : False } }] }): print cursor['screenname'] print cursor['_id']['uid'] id = cursor['_id']['uid'] 

Sin embargo, después de un corto tiempo, recibo este error:

pymongo.errors.CursorNotFound: el ID del cursor ‘…’ no es válido en el servidor.

Encontré este artículo que se refiere a ese problema. Sin embargo, no me queda claro qué solución tomar. ¿Es posible usar find().batch_size(30) ? ¿Qué hace exactamente el comando anterior? ¿Puedo tomar todos los identificadores de base de datos utilizando batch_size ?

Recibirá este error porque el cursor está agotando el tiempo de espera en el servidor (después de 10 minutos de inactividad).

De la documentación del pymongo:

Los cursores en MongoDB pueden agotar el tiempo de espera en el servidor si han estado abiertos durante mucho tiempo sin que se realicen operaciones en ellos. Esto puede provocar que se genere una excepción CursorNotFound cuando se intenta iterar el cursor.

Cuando llama al método collection.find , consulta una colección y devuelve un cursor a los documentos. Para obtener los documentos debes iterar el cursor. Cuando recorre el cursor, el controlador está realizando solicitudes al servidor MongoDB para obtener más datos del servidor. La cantidad de datos devueltos en cada solicitud se establece mediante el método batch_size() .

De la documentación :

Limita el número de documentos devueltos en un lote. Cada lote requiere un viaje de ida y vuelta al servidor. Se puede ajustar para optimizar el rendimiento y limitar la transferencia de datos.

Establecer el tamaño de lote en un valor más bajo le ayudará con los errores de tiempo de espera, pero boostá el número de veces que obtendrá acceso al servidor MongoDB para obtener todos los documentos.

El tamaño de lote predeterminado:

Para la mayoría de las consultas, el primer lote devuelve 101 documentos o solo documentos suficientes para exceder 1 megabyte. El tamaño del lote no superará el tamaño máximo del documento BSON (16 MB).

No hay un tamaño de lote universal “correcto”. Debe probar con diferentes valores y ver cuál es el valor apropiado para su caso de uso, es decir, cuántos documentos puede procesar en una ventana de 10 minutos.

El último recurso será que establezca el timeout=False . Pero debe asegurarse de que el cursor esté cerrado después de terminar de procesar los datos.

Use no_cursor_timeout=True como este:

 cursor=db.images.find({}, {'id':1, 'image_path':1, '_id':0}, no_cursor_timeout=True) for i in cursor: # ..... # ..... cursor.close() # use this or cursor keeps waiting so ur resources are used up 

Estabas usando el cursor más que el tiempo de espera (unos 10 minutos) por lo que el cursor ya no existe.

debe elegir un valor bajo de batch_size para solucionar el problema:

(con Pymongo por ejemplo)

 col.find({}).batch_size(10) 

o

establezca el tiempo de espera en false col.find(timeout=False) y no olvide cerrar el cursor al final.