sql >> Base de Datos >  >> NoSQL >> MongoDB

Upsert rápido o masivo en pymongo

Las versiones modernas de pymongo (superiores a 3.x) envuelven las operaciones masivas en una interfaz consistente que degrada cuando la versión del servidor no admite operaciones masivas. Esto ahora es consistente en los controladores admitidos oficialmente por MongoDB.

Entonces, el método preferido para codificar es usar bulk_write() en cambio, donde usa un UpdateOne otra acción de operación apropiada en su lugar. Y ahora, por supuesto, se prefiere usar las listas de lenguaje natural en lugar de un constructor específico

La traducción directa de la documentación antigua:

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 el bucle clásico de transformación de documentos:

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)

El resultado devuelto es de BulkWriteResult que contendrá contadores de documentos coincidentes y actualizados, así como el _id devuelto valores para cualquier "inserción" que ocurra.

Existe una idea errónea sobre el tamaño de la matriz de operaciones masivas. La solicitud real tal como se envió al servidor no puede exceder el límite BSON de 16 MB, ya que ese límite también se aplica a la "solicitud" enviada al servidor que también utiliza el formato BSON.

Sin embargo, eso no rige el tamaño de la matriz de solicitudes que puede crear, ya que las operaciones reales solo se enviarán y procesarán en lotes de 1000 de todos modos. La única restricción real es que esas 1000 instrucciones de operación en sí mismas no crean un documento BSON de más de 16 MB. Que de hecho es una tarea bastante difícil.

El concepto general de los métodos masivos es "menos tráfico", como resultado de enviar muchas cosas a la vez y solo tratar con una respuesta del servidor. La reducción de esa sobrecarga adjunta a cada solicitud de actualización ahorra mucho tiempo.