41 votes

mongodb curseur id n'est pas valide erreur

Je suis en train de parcourir cette boucle:

for doc in coll.find()

J'obtiens l'erreur suivante lors de la 100 000 ème et d'enregistrer.

File "build\bdist.win32\egg\pymongo\cursor.py", line 703, in next
File "build\bdist.win32\egg\pymongo\cursor.py", line 679, in _refresh
File "build\bdist.win32\egg\pymongo\cursor.py", line 628, in __send_message
File "build\bdist.win32\egg\pymongo\helpers.py", line 95, in _unpack_response
pymongo.errors.OperationFailure: cursor id '1236484850793' not valid at server

que signifie cette erreur signifie?

38voto

Reto Aebersold Points 6144

Peut-être que votre curseur expiré sur le serveur. Pour voir si c'est le problème, essayez de timeout=False`:

for doc in coll.find(timeout=False)

Voir http://api.mongodb.org/python/1.6/api/pymongo/collection.html#pymongo.collection.Collection.find

Si c'était un problème de délai d'attente d'une solution possible est de mettre la batch_size (. s. d'autres réponses).

36voto

Oran Points 485
  • Réglage de l' timeout=False est dangereux et ne doit jamais être utilisé, car la connexion avec le curseur peut rester ouvert pendant une période de temps illimitée, qui aura une incidence sur les performances du système. Les docs expressément référence à la nécessité de fermer manuellement le curseur.
  • Réglage de l' batch_size à un petit nombre de fonctionner, mais crée un gros problème de latence, parce que nous avons besoin pour accéder à la DB plus souvent que nécessaire.
    Par exemple:
    5M docs avec un petit lot va prendre des heures pour récupérer les mêmes données qu'un défaut batch_size retourne dans plusieurs minutes.

Dans ma solution, il est obligatoire d'utiliser le tri sur le curseur:

done = False
skip = 0
while not done:
    cursor = coll.find()
    cursor.sort( indexed_parameter ) # recommended to use time or other sequential parameter.
    cursor.skip( skip )
    try:
        for doc in cursor:
            skip += 1
            do_something()
        done = True
    except pymongo.errors.OperationFailure, e:
        msg = e.message
        if not ( msg.startswith( "cursor id" ) and msg.endswith( "not valid at server" ) )
            raise

26voto

jiehanzheng Points 392

Paramètre timeout=False est une très mauvaise pratique. Une meilleure façon de se débarrasser du curseur id exception délai est d'estimer le nombre de documents à votre boucle de processus dans un délai de 10 minutes, et de venir avec un conservateur de la taille des lots. De cette façon, la MongoDB client (dans ce cas, PyMongo) aura pour interroger le serveur de temps en temps que les documents dans le lot précédent ont été utilisés. Cela permet de garder le curseur actif sur le serveur, et vous sera toujours couvert par la à 10 minutes de délai d'expiration de la protection.

Voici comment vous définissez la taille du lot pour un curseur:

for doc in coll.find().batch_size(30):
    do_time_consuming_things()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X