insérer ou ignorer plusieurs documents en mongoDB

j'ai une collection dans laquelle tous mes documents ont au moins ces 2 champs, dire name et url (où url est unique donc j'ai mis en place un index unique dessus). Maintenant, si j'essaie d'insérer un document avec un double url, il va donner une erreur et arrête le programme. Je ne veux pas ce comportement, mais j'ai besoin de quelque chose comme mysqlinsert or ignore, de sorte que mongoDB ne doit pas insérer le document avec un double url et continuer avec les documents suivants.

y a-t-il un paramètre que je peux passer à insert commande pour atteindre ce comportement? Je fais généralement un lot d'inserts en utilisant pymongo comme:

collection.insert(document_array)

Ici collection est une collection et document_array est un tableau de documents.

il y a donc un moyen que je puisse implémenter le insert or ignore fonctionnalité pour un insert de document multiple?

10
demandé sur McGarnagle 2012-04-30 22:16:31

7 réponses

mettre le continue_on_error drapeau lors de l'appel de insert (). Note PyMongo pilote 2.1 et le serveur de la version 1.9.1 sont requises:

continue_on_error( optionnel): Si True, La base de données ne s'arrêtera pas traitement d'un encart en vrac si l'un d'eux échoue (par exemple en raison d'une duplication D'IDs). Cela rend l'insert en vrac se comporter de la même façon qu'une série d'inserts simples, sauf que lastError sera réglé si un insert échoue, pas seulement le dernier un. Si plusieurs erreurs se produisent, la plus récente sera être signalé par erreur().

13
répondu Leftium 2012-09-04 17:07:52

essaye ceci:

try:
    coll.insert(
        doc_or_docs=doc_array,
        continue_on_error=True)
except pymongo.errors.DuplicateKeyError:
    pass

l'opération insert lancera toujours une exception si une erreur se produit dans l'insert (comme essayer d'insérer une valeur dupliquée pour un index unique), mais elle n'affectera pas les autres éléments du tableau. Vous pouvez ensuite avaler l'erreur comme indiqué ci-dessus.

11
répondu William Payne 2012-09-04 16:37:47

utilisez insert_many (), et set ordered=False.

cela garantit que toutes les opérations d'écriture sont tentées, même s'il y a des erreurs: http://api.mongodb.org/python/current/api/pymongo/collection.html#pymongo.collection.Collection.insert_many

10
répondu barlaso 2015-08-04 04:24:57

Pourquoi ne pas simplement mettre votre appel à .insert() dans un try: ... except: bloc et continuer si l'insertion échoue?

En outre, vous pouvez également utiliser un update() appel upsert drapeau. Plus de détails ici: http://www.mongodb.org/display/DOCS/Updating#Updating-update%28%29

0
répondu mpobrien 2012-04-30 18:58:38

si vous avez votre tableau de documents déjà en mémoire dans votre script python, pourquoi ne pas les insérer en itérant à travers eux, et simplement attraper ceux qui échouent lors de l'insertion en raison de l'index unique?

for doc in docs:
  try:
    collection.insert(doc)
  except pymongo.errors.DuplicateKeyError:
    print 'Duplicate url %s' % doc

où collection est une instance d'une collection créée à partir de vos instances de connexion/base de données et docs est le tableau de dictionnaires (documents) que vous passeriez actuellement à insérer.

Vous pouvez aussi décider quoi faire avec les doubles de clés qui violent votre index unique dans le except bloc.

0
répondu DeaconDesperado 2012-04-30 19:00:22

Il est fortement recommandé d'utiliser upsert

  stat.update({'location': d['user']['location']}, \
       {'$inc': {'count': 1}},upsert = True, safe = True)

Ici stat est la collection si la position du visiteur est déjà présent dans la collection, count est augmenté d'un, sinon count est réglé sur 1.

voici le lien pour la documentation http://www.mongodb.org/display/DOCS/Updating#Updating-UpsertswithModifiers

-2
répondu Kracekumar 2012-04-30 19:10:32

Ce que je fais :

  1. génère un tableau de MongoDB id je veux insérer (hachage de certaines valeurs dans mon cas)
  2. Enlever les Id (je suis à l'aide d'un Redis file d'attente bcoz la performance, mais vous pouvez interroger mongo)
  3. Insérez vos données nettoyées !

Redis est parfait pour cela, vous pouvez utiliser la mémoire Memcached ou Mysql, en fonction de vos besoins

-2
répondu Thomas Decaux 2012-08-29 14:47:34