Overview
Esta guía le muestra cómo utilizar el controlador Scala para realizar una operación de escritura masiva que realiza múltiples cambios en sus datos en una sola llamada a la base de datos.
Considere una situación que requiere insertar, actualizar y eliminar documentos para la misma tarea. Si utiliza los métodos de escritura individuales para cada tipo de operación, cada escritura accede a la base de datos por separado. Puede usar una operación de escritura masiva para optimizar el número de llamadas que su aplicación realiza al servidor.
Datos de muestra
Los ejemplos de esta guía utilizan el restaurants colección en la base de datos sample_restaurants de la Conjuntos de datos de muestra de Atlas. Para acceder a esta colección desde su aplicación Scala, cree un MongoClient que se conecte a un clúster de Atlas y asigne los siguientes valores a las variables database collection y:
val database: MongoDatabase = mongoClient.getDatabase("sample_restaurants") val collection: MongoCollection[Document] = database.getCollection("restaurants")
Para aprender cómo crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de muestra, consulte la guía de introducción a MongoDB.
Definir las operaciones de escritura
Para cada operación de escritura que desee realizar, cree una instancia correspondiente de una de las siguientes clases de operación que heredan de la clase genérica WriteModel:
InsertOneModelUpdateOneModelUpdateManyModelReplaceOneModelDeleteOneModelDeleteManyModel
Luego, pase una lista de estas instancias al método bulkWrite().
Las siguientes secciones muestran cómo crear y usar instancias de las clases anteriores. La sección "Realizar la operación masiva" muestra cómo pasar una lista de modelos al bulkWrite() método para realizar la operación masiva.
Operaciones de inserción
Para realizar una operación de inserción, cree una instancia InsertOneModel y especifique el documento que desea insertar.
El siguiente ejemplo crea una instancia de InsertOneModel:
val insertOneModel = InsertOneModel( Document("name" -> "Blue Moon Grill", "borough" -> "Brooklyn", "cuisine" -> "American") )
Para insertar varios documentos, cree una instancia de InsertOneModel para cada documento.
Importante
Al realizar una operación masiva, el InsertOneModel no puede insertar un documento con un _id ya existente en la colección. En este caso, el controlador lanza un MongoBulkWriteException.
Operaciones de actualizar
Para actualizar un documento, crea una instancia de UpdateOneModel y pasa los siguientes argumentos:
Filtro de consulta que especifica los criterios utilizados para buscar coincidencias en los documentos de su colección.
Operación de actualización que desea realizar. Para más información sobre las operaciones de actualización, consulte la guía "Operadores de actualización de campos" en el manual de MongoDB Server.
El siguiente ejemplo crea una instancia de UpdateOneModel:
val updateOneFilter = equal("name", "White Horse Tavern") val updateOneDoc = set("borough", "Queens") val updateOneModel = UpdateOneModel(updateOneFilter, updateOneDoc)
Si varios documentos coinciden con el filtro de consulta especificado en la instancia UpdateOneModel, la operación actualiza el primer resultado. Puede especificar una ordenación en una instancia UpdateOptions para aplicar un orden a los documentos coincidentes antes de que el controlador realice la operación de actualización, como se muestra en el siguiente código:
val options = UpdateOptions.sort(ascending("name"))
Para actualizar varios documentos, cree una instancia de UpdateManyModel y pase los mismos argumentos que UpdateOneModel para. La UpdateManyModel clase especifica las actualizaciones para todos los documentos que coinciden con su filtro de consulta.
El siguiente ejemplo crea una instancia de UpdateManyModel:
val updateManyFilter = equal("name", "Wendy's") val updateManyDoc = set("cuisine", "Fast food") val updateManyModel = UpdateOneModel(updateManyFilter, updateManyDoc)
Reemplazar operaciones
Una operación de reemplazo elimina todos los campos y valores de un documento específico y los reemplaza con los nuevos campos y valores que usted especifique. Para realizar una operación de reemplazo, cree una instancia de ReplaceOneModel y pase los siguientes argumentos:
Filtro de consulta que especifica los criterios utilizados para buscar coincidencias en los documentos de su colección
Documento de reemplazo que especifica los nuevos campos y valores a insertar
El siguiente ejemplo crea una instancia de ReplaceOneModel:
val replaceFilter = equal("name", "Cooper Town Diner") val replaceDoc = Document("name" -> "Smith Town Diner", "borough" -> "Brooklyn", "cuisine" -> "American") val replaceOneModel = ReplaceOneModel(replaceFilter, replaceDoc)
Si varios documentos coinciden con el filtro de consulta especificado en la instancia ReplaceOneModel, la operación reemplaza el primer resultado. Puede especificar una ordenación en una instancia ReplaceOptions para aplicar un orden a los documentos coincidentes antes de que el controlador realice la operación de reemplazo, como se muestra en el siguiente código:
val options = ReplaceOptions.sort(ascending("name"))
Tip
Reemplazar varios documentos
Para reemplazar varios documentos, cree una instancia de ReplaceOneModel para cada documento.
Operaciones de borrar
Para borrar un documento, crea una instancia de DeleteOneModel y pasa un filtro de query que especifique el documento que deseas borrar. Una instancia DeleteOneModel proporciona instrucciones para eliminar solo el primer documento que coincida con tu filtro de query.
El siguiente ejemplo crea una instancia de DeleteOneModel:
val deleteOneModel = DeleteOneModel(equal("name", "Morris Park Bake Shop"))
Para eliminar varios documentos, cree una instancia de DeleteManyModel y utilice un filtro de consulta que especifique el documento que desea eliminar. Una instancia de DeleteManyModel proporciona instrucciones para eliminar todos los documentos que coincidan con su filtro de consulta.
El siguiente ejemplo crea una instancia de DeleteManyModel:
val deleteManyModel = DeleteManyModel(equal("cuisine", "Experimental"))
Realizar la operación masiva
Después de definir una instancia de modelo para cada operación que desee realizar, pase una lista de estas instancias al método bulkWrite(). De forma predeterminada, el método ejecuta las operaciones en el orden especificado por la lista de modelos.
El siguiente ejemplo realiza múltiples operaciones de escritura utilizando el método bulkWrite():
val insertOneModel = InsertOneModel( Document("name" -> "Red's Pizza", "borough" -> "Brooklyn", "cuisine" -> "Pizzeria") ) val updateOneModel = UpdateOneModel(equal("name", "Moonlit Tavern"), set("borough", "Queens")) val deleteManyModel = DeleteManyModel(equal("name", "Crepe")) val writes = Seq(insertOneModel, updateOneModel, deleteManyModel) val observable = collection.bulkWrite(writes) observable.subscribe( (result: BulkWriteResult) => println(s"Success: $result"), (error: Throwable) => println(s"Error: ${error.getMessage}"), () => println("Completed") )
Success: AcknowledgedBulkWriteResult{insertedCount=1, matchedCount=1, removedCount=1, modifiedCount=1, upserts=[], inserts=[BulkWriteInsert{index=0, id=BsonObjectId{value=...}}]} Completed
Si alguna de las operaciones de escritura falla, el controlador Scala genera un BulkWriteError y no realiza ninguna operación adicional. BulkWriteError proporciona un elemento details que incluye la operación que falló y detalles sobre la excepción.
Nota
Cuando el controlador ejecuta una operación masiva, utiliza la preocupación de escritura de la colección de destino. El controlador informa todos los errores de preocupación de escritura después de intentar todas las operaciones, independientemente del orden de ejecución.
Personalizar la operación de escritura masiva
El método bulkWrite() acepta opcionalmente un parámetro BulkWriteOptions, que especifica las opciones que se pueden usar para configurar la operación de escritura masiva. Si no se especifica ninguna opción, el controlador realiza la operación masiva con la configuración predeterminada.
La siguiente tabla describe los métodos de configuración que puede utilizar para configurar una instancia BulkWriteOptions:
Método | Descripción |
|---|---|
| If true, the driver performs the write operations in the order
provided. If an error occurs, the remaining operations are not
attempted.If false, the driver performs the operations in an
arbitrary order and attempts to perform all operations.Defaults to true. |
| Specifies whether the update operation bypasses document validation. This lets you
update documents that don't meet the schema validation requirements, if any
exist. For more information about schema validation, see Schema
Validation in the MongoDB
Server manual. Defaults to false. |
| Sets a comment to attach to the operation. |
| Provides a map of parameter names and values to set top-level
variables for the operation. Values must be constant or closed
expressions that don't reference document fields. |
El siguiente código crea opciones y establece la opción ordered en false para especificar una escritura masiva desordenada. Luego, el ejemplo usa el método bulkWrite() para realizar una operación masiva:
val options = BulkWriteOptions().ordered(false) val observable = collection.bulkWrite(writes, options)
Si alguna de las operaciones de escritura en una escritura en bloque desordenada falla, el driver de Scala informa los errores solo después de intentar todas las operaciones.
Nota
Las operaciones masivas desordenadas no garantizan un orden de ejecución. El orden puede variar según la forma en que se enumeran para optimizar el tiempo de ejecución.
Valor de retorno
El método bulkWrite() devuelve un objeto SingleObservable que contiene un BulkWriteResult. Puede acceder a la información de la instancia BulkWriteResult suscribiéndose al observable y utilizando los siguientes métodos:
Método | Descripción |
|---|---|
| Indicates if the server acknowledged the write operation. |
| The number of documents deleted, if any. |
| The number of documents inserted, if any. |
| The list of inserted documents, if any. |
| The number of documents matched for an update, if applicable. |
| The number of documents modified, if any. |
| The list of upserted documents, if any. |
Información Adicional
Para aprender a realizar operaciones de escritura individuales, consulte las siguientes guías:
Documentación de la API
Para aprender más sobre cualquiera de los métodos o tipos analizados en esta guía, consulta la siguiente documentación de API: