2016-02-18 2 views
3

Je veux mettre à jour des milliers de documents dans la collection mongo. Je veux les trouver en utilisant ObjectId et ensuite quel document correspond, devrait être mis à jour. Ma mise à jour est la même pour tous les documents. J'ai la liste d'ObjectId. Pour chaque ObjectId dans la liste, mongo devrait trouver correspondant à documenter et mettre à jour « isBad » clé de ce document à « N »Mise à jour en masse dans Pymongo en utilisant plusieurs ObjectId

ids = [ObjectId('56ac9d3fa722f1029b75b128'), ObjectId('56ac8961a722f10249ad0ad1')] 
bulk = db.testdata.initialize_unordered_bulk_op() 
bulk.find({ '_id': ids}).update({ '$set': { "isBad" : "N" } }) 
print bulk.execute() 

Cela me donne le résultat:

{'nModified': 0, 'nUpserted': 0, 'nMatched': 0, 'writeErrors': [], 'upserted': [], 'writeConcernErrors': [], 'nRemoved': 0, 'nInserted': 0} 

Cela devrait, car il tente pour faire correspondre "_id" avec la liste. Mais je ne sais pas comment procéder.

Je sais comment mettre à jour chaque document individuellement. Ma taille de liste est de l'ordre de 25 000. Je ne veux pas faire 25 000 appels individuellement. Le nombre de documents dans ma collection est beaucoup plus. J'utilise python2, pymongo = 3.2.1.

Répondre

-1

Je suis la réponse, il peut être fait comme ceci:

bulk = db.testdata.initialize_unordered_bulk_op() 
    for i in range (0, len(ids)): 
     bulk.find({ '_id': ids[i]}).update({ '$set': { "isBad" : "N" }}) 
    print bulk.execute() 
+1

pourquoi avez-vous besoin 'range' this est inefficace. – styvane

6

Itérer la liste id en utilisant une boucle et envoyer les mises à jour en vrac par lots de 500:

bulk = db.testdata.initialize_unordered_bulk_op() 
counter = 0 

for id in ids: 
    # process in bulk 
    bulk.find({ '_id': id }).update({ '$set': { 'isBad': 'N' } }) 
    counter += 1 

    if (counter % 500 == 0): 
     bulk.execute() 
     bulk = db.testdata.initialize_ordered_bulk_op() 

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

Parce que les commandes d'écriture peuvent accepter plus de 1000 opérations (de la docs) , vous devrez diviser les opérations en masse en plusieurs lots, dans ce cas vous pouvez choisir une taille de lot arbitraire allant jusqu'à 1000.

La raison du choix de 500 est de s'assurer que la somme des d le document Bulk.find() et le document de mise à jour est inférieur ou égal à la taille maximale du document BSON, même s'il n'y a pas de garantie que les demandes d'opérations par défaut de 1000 correspondront à la limite BSON de 16 Mo. Les Bulk() opérations dans le shell mongo et des méthodes comparables dans les pilotes n'ont pas cette limite.

+0

pourquoi ne pas dépasser 500? –

+0

@PratikGujarathi Ajout de lecture pour le choix. – chridam

+1

'count ++' échouera dans l'utilisation de Python' count = count + 1' ou 'count + = 1' – styvane