Você está recebendo este erro porque o cursor está expirando no servidor (após 10 minutos de inatividade).
Da documentação do pymongo:
Os cursores no MongoDB podem atingir o tempo limite no servidor se estiverem abertos por muito tempo sem que nenhuma operação seja executada neles. Isso pode levar a uma exceção CursorNotFound sendo gerada ao tentar iterar o cursor.
Quando você chama o
collection.find
ele consulta uma coleção e retorna um cursor para os documentos. Para obter os documentos, você itera o cursor. Quando você itera sobre o cursor, o driver está, na verdade, fazendo solicitações ao servidor MongoDB para buscar mais dados do servidor. A quantidade de dados retornados em cada solicitação é definida pelo batch_size()
método. Da documentação:
Limita o número de documentos devolvidos em um lote. Cada lote requer uma viagem de ida e volta ao servidor. Ele pode ser ajustado para otimizar o desempenho e limitar a transferência de dados.
Definir o batch_size para um valor menor ajudará você com os erros de tempo limite, mas aumentará o número de vezes que você acessará o servidor MongoDB para obter todos os documentos.
O tamanho do lote padrão:
Para a maioria das consultas, o primeiro lote retorna 101 documentos ou apenas documentos suficientes para exceder 1 megabyte. O tamanho do lote não excederá o tamanho máximo do documento BSON (16 MB).
Não existe um tamanho de lote "certo" universal. Você deve testar com valores diferentes e ver qual é o valor apropriado para o seu caso de uso, ou seja, quantos documentos você pode processar em uma janela de 10 minutos.
O último recurso será definir
no_cursor_timeout=True
. Mas você precisa ter certeza de que o cursor está fechado após concluir o processamento dos dados. Como evitá-lo sem
try/except
:cursor = collection.find(
{"x": 1},
no_cursor_timeout=True
)
for doc in cursor:
# do something with doc
cursor.close()