9
votes

La meilleure façon de lire et mettre à jour les documents de MongoDB en utilisant pymongo

iam essayant de lire un document de collection de MongoDB par document afin d'aller chercher chaque enregistrement chiffrer certains des champs dans l'enregistrement et de le remettre à la base de données.

list_coll = [record for record in coll.find()]
for rec in list_coll:
   #modifying record
   coll.update(rec)


5 commentaires

Je ne peux pas penser à une meilleure façon, donc je ne remplirai pas une réponse. Recommander le générateur sur la création de liste d'enregistrements serait probablement fou depuis que je pense que vous auriez le même problème. J'utiliserais probablement votre solution, bien que si je devais mettre à jour une très grande collection, je supporterais des enregistrements de valeurs inutiles tout en créant la liste, juste pour économiser un espace supplémentaire (ce qui pourrait empêcher le «débordement de RAM»). Si vous pensez que c'est un scénario réaliste, vous devriez probablement prendre un peu de la collection à la fois. (Remarque: vous pouvez ajouter du drapeau aux enregistrements modifiés et utiliser le premier extrait, mais avec des frais généraux)


Oui, mais ma liste à rayures sera également grande que c'est mon problème.


@Wudpecker Je pense que la vraie chose ici est "Qu'est-ce que tu essayes de faire?" La boucle avec une requête «rien» n'a de sens quand il y a une intention spécifique ou une signification autrement, ce qui signifie que vous devez «lire» une valeur et la modifier, puis écrivez quelque chose de retour. Mais si vous voulez simplement modifier quelque chose, il y a généralement une meilleure façon. Alors essayez de modifier votre question pour dire ce que vous voulez réellement faire. Ensuite, vous obtenez de vraies réponses.


merci @neillunn, édité


D'accord. Au moins l'intention est plus claire. Il y a une meilleure façon qui ne soit pas encore traitée depuis ma lecture.


3 Réponses :


3
votes

Si votre collection n'est pas faite, vous pouvez isoler votre Curseur de consulter le même Doc après sa mise à jour en utilisant le instantané paramètre: xxx

si votre collection est Sharded, conservez une variable de hachage des valeurs que vous avez déjà mises à jour, puis vérifiez cette liste avant de modifier chaque enregistrement pour vous assurer que vous ne vous mettez pas à jour deux fois. < / p>



9
votes

Vous voulez que le "API d'opérations en vrac" de MongoDB. Principalement introduit avec MongoDb 2.6, une raison convaincante de la mise à niveau si vous n'avez pas actuellement.

bulk = db.coll.initialize_ordered_bulk_op()
counter = 0

for record in coll.find(snapshot=True):
    # now process in bulk
    # calc value first
    bulk.find({ '_id': record['_id'] }).update({ '$set': { 'field': newValue } })
    counter += 1

    if counter % 1000 == 0:
        bulk.execute()
        bulk = db.coll.initialize_ordered_bulk_op()

if counter % 1000 != 0:
    bulk.execute()


2 commentaires

Est-ce que cet initialize_Ordered_bulk_op () fonctionne avec PymonGo 2.5


Les opérations d'insertion en vrac @Wudpecker ont été introduites dans PymonGo 2.6 et des opérations mixtes, y compris des mises à jour à partir de 2,7. L'exigence principale est la version du serveur de MongoDB 2.6 ou supérieure, que si vous avez déjà en place, vous devez également envisager de mettre à niveau également la mise à niveau de votre bibliothèque cliente.



0
votes

Marquez chaque enregistrement comme mis à jour, par exemple. En ajoutant un drapeau ou en veillant à ce que le champ mis à jour a une certaine forme pouvant être assortie par une requête.

Utilisez la requête pour correspondre uniquement aux documents qui n'ont pas encore été mis à jour et vérifiez chaque document lorsque vous ithétiez.

Pourquoi?

  • Parce que la collection peut être trop grande pour gérer les identifiants mis à jour dans un hachage local

  • Parce que votre processus pourrait se bloquer et quitter la collection dans un état demi-mis à jour. Vous voudrez peut-être pouvoir le reprendre.

    S'il s'agit d'un travail unique sur une collection non fragile, envisagez d'utiliser une requête d'instantanée.


0 commentaires