Visão geral
Neste guia, você pode aprender como acessar dados de um cursor com o PyMongo.
Um cursor é um mecanismo que retorna os resultados de uma operação de leitura em lotes iteráveis. Como um cursor contém apenas um subconjunto de documentos a qualquer momento, os cursores reduzem o consumo de memória e o uso da largura de banda da rede.
Sempre que o PyMongo executa uma operação de leitura que retorna vários documentos, ele retorna automaticamente esses documentos em um cursor.
Dados de amostra
Os exemplos neste guia usam a collection sample_restaurants.restaurants dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster gratuito do MongoDB Atlas e carregar os conjuntos de dados de amostra, consulte o tutorial Introdução ao PyMongo .
Acesse o conteúdo do cursor iterativamente
Para iterar sobre o conteúdo de um cursor, use um loop for, como mostrado no exemplo a seguir. Selecione a aba Synchronous ou Asynchronous para ver o código correspondente:
results = collection.find()
for document in results: print(document)results = collection.find()
async for document in results: print(document)Recuperar documentos individualmente
Recupere documentos de um cursor individualmente chamando o método next() .
O exemplo a seguir encontra todos os documentos em uma collection com um valor de name "Dunkin' Donuts". Em seguida, ele imprime o primeiro documento no cursor chamando o método next(). Selecione a aba Synchronous ou Asynchronous para ver o código correspondente:
results = collection.find({ "name": "Dunkin' Donuts" })
print(results.next())results = collection.find({ "name": "Dunkin' Donuts" })
print(await results.next())Recuperar todos os documentos
Aviso
Se o número e o tamanho dos documentos retornados pela sua query excederem a memória disponível do aplicativo, seu programa falhará. Se você espera um conjunto de resultados grande, acesse o cursor iterativamente.
Para recuperar todos os documentos de um cursor, converta o cursor em um list, como mostrado no exemplo a seguir. Selecione a aba Synchronous ou Asynchronous para ver o código correspondente:
results = collection.find({ "name": "Dunkin' Donuts" })
all_results = list(results)
for document in all_results: print(document)results = collection.find({ "name": "Dunkin' Donuts" })
all_results = await to_list(results)
for document in all_results: print(document)Fechar um cursor
Por padrão, o MongoDB fecha um cursor quando o cliente esgota todos os resultados no cursor. Para fechar explicitamente um cursor, chame o método close() como mostrado no exemplo a seguir. Selecione a aba Synchronous ou Asynchronous para ver o código correspondente:
results = collection.find()
...
results.close()results = collection.find()
...
await results.close()Você também pode instanciar um cursor em uma declaração with, como mostrado no exemplo a seguir. O PyMongo fecha automaticamente o cursor quando o bloqueio termina.
with collection.find() as cursor: for document in cursor: print(document)Cursores persistentes
Ao fazer query em uma collection limitada, você pode usar um cursor persistente que permanece aberto depois que o cliente esgota os resultados em um cursor. Para criar um cursor persistente com collection limitada, especifique CursorType.TAILABLE_AWAIT na opção cursor_type de um método find() .
O exemplo a seguir usa um cursor persistente para rastrear o oplog de um membro do conjunto de réplicas. Selecione a aba Synchronous ou Asynchronous para ver o código correspondente:
oplog = client.local.oplog.rsfirst = oplog.find().sort('$natural', pymongo.ASCENDING).limit(-1).next()print(first)ts = first['ts']
while True: cursor = oplog.find({'ts': {'$gt': ts}}, cursor_type=pymongo.CursorType.TAILABLE_AWAIT) while cursor.alive: for doc in cursor: ts = doc['ts'] print(doc)
# You end up here if the find() method returns no documents, or if # no new documents are added to the collection for more than 1 second. time.sleep(1)oplog = client.local.oplog.rsfirst = await oplog.find().sort('$natural', pymongo.ASCENDING).limit(-1).next()print(first)ts = first['ts']
while True: cursor = oplog.find({'ts': {'$gt': ts}}, cursor_type=pymongo.CursorType.TAILABLE_AWAIT) while cursor.alive: async for doc in cursor: ts = doc['ts'] print(doc)
# You end up here if the find() method returns no documents, or if # no new documents are added to the collection for more than 1 second. await asyncio.sleep(1)Para saber mais sobre cursores tailable, consulte o guia Cursores tailable no manual do MongoDB Server .
Solução de problemas
O objeto 'Cursor' não tem atributo '_Cursor__killed'
O PyMongo v3.8 ou anterior gera um TypeError e um AttributeError se você fornecer argumentos inválidos para o construtor Cursor . O AttributeError é irrelevante, mas o TypeError contém informações de depuração, conforme mostrado no exemplo a seguir:
Exception ignored in: <function Cursor.__del__ at 0x1048129d8>...AttributeError: 'Cursor' object has no attribute '_Cursor__killed'...TypeError: __init__() got an unexpected keyword argument '<argument>'Para corrigir isso, certifique-se de fornecer os argumentos de palavra-chave corretos. Você também pode atualizar para o PyMongo v3.9 ou posterior, o que remove o erro irrelevante.
"CursorNotFound ID de cursor inválido no servidor"
Os cursores no MongoDB podem atingir o tempo limite no servidor se estiverem abertos há muito tempo sem que nenhuma operação seja executada neles. Isso pode levar a uma exceção CursorNotFound quando você tenta iterar pelo cursor.