MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Upsert veloce o sfuso in pymongo

Le versioni moderne di pymongo ( maggiori di 3.x ) racchiudono le operazioni in blocco in un'interfaccia coerente che esegue il downgrade laddove la versione del server non supporta le operazioni in blocco. Questo è ora coerente nei driver MongoDB ufficialmente supportati.

Quindi il metodo preferito per la codifica è usare bulk_write() invece, dove usi un UpdateOne invece altra opportuna azione operativa. E ora, ovviamente, è preferibile utilizzare gli elenchi in linguaggio naturale piuttosto che un builder specifico

La traduzione diretta della vecchia documentazione:

from pymongo import UpdateOne

operations = [
    UpdateOne({ "field1": 1},{ "$push": { "vals": 1 } },upsert=True),
    UpdateOne({ "field1": 1},{ "$push": { "vals": 2 } },upsert=True),
    UpdateOne({ "field1": 1},{ "$push": { "vals": 3 } },upsert=True)
]

result = collection.bulk_write(operations)

O il classico ciclo di trasformazione dei documenti:

import random
from pymongo import UpdateOne

random.seed()

operations = []

for doc in collection.find():
    # Set a random number on every document update
    operations.append(
        UpdateOne({ "_id": doc["_id"] },{ "$set": { "random": random.randint(0,10) } })
    )

    # Send once every 1000 in batch
    if ( len(operations) == 1000 ):
        collection.bulk_write(operations,ordered=False)
        operations = []

if ( len(operations) > 0 ):
    collection.bulk_write(operations,ordered=False)

Il risultato restituito è BulkWriteResult che conterrà i contatori di documenti abbinati e aggiornati, nonché il _id restituito valori per eventuali "upsert" che si verificano.

C'è un po' di un'idea sbagliata sulla dimensione dell'array delle operazioni di massa. La richiesta effettiva inviata al server non può superare il limite di 16 MB BSON poiché tale limite si applica anche alla "richiesta" inviata al server che utilizza anche il formato BSON.

Tuttavia ciò non regola la dimensione dell'array di richieste che è possibile creare, poiché le operazioni effettive verranno comunque inviate ed elaborate solo in batch di 1000. L'unica vera limitazione è che quelle 1000 istruzioni operative stesse non creano effettivamente un documento BSON maggiore di 16 MB. Che è davvero un compito piuttosto arduo.

Il concetto generale dei metodi di massa è "meno traffico", come risultato dell'invio di molte cose contemporaneamente e della gestione di una sola risposta del server. La riduzione dell'overhead associato a ogni singola richiesta di aggiornamento consente di risparmiare un sacco di tempo.