Overview
En esta guía, puede aprender a utilizar operaciones masivas en el controlador MongoDB Kotlin.
Para operaciones CRUD individuales, puede usar el método correspondiente. Por ejemplo, para insertar un documento y luego actualizar varios, puede usar el insertOne() método y el método updateMany().
El MongoClient realiza estas operaciones mediante una solicitud a la base de datos correspondiente a cada operación. Puede reducir el número de llamadas a la base de datos mediante operaciones masivas.
Realización de operaciones masivas
Las operaciones masivas consisten en un gran número de operaciones de escritura. Para realizar una operación masiva, pase un List que contenga WriteModel documentos al método bulkWrite(). Un WriteModel es un modelo que representa una sola operación de escritura.
Las siguientes secciones muestran cómo crear y usar cada variación del tipo WriteModel. Los ejemplos de cada sección utilizan los siguientes documentos en la colección people:
{ "_id": 1, "name": "Karen Sandoval", "age": 31 } { "_id": 2, "name": "William Chin", "age": 54 } { "_id": 8, "name": "Shayla Ray", "age": 20 }
Estos datos se modelan con la siguiente clase de datos Kotlin:
data class Person( val id: Int, val name: String, val age: Int? = null, val location: String? = null )
Para obtener más información sobre los métodos y clases mencionados en esta sección, consulte la siguiente documentación de API:
Operación de inserción
Para insertar un documento, cree un InsertOneModel que especifique el documento que desea insertar. Para insertar varios documentos, debe crear un InsertOneModel para cada uno.
Ejemplo
El siguiente ejemplo crea un InsertOneModel para dos documentos que describen personas:
val juneDoc = InsertOneModel(Person(3, "June Carrie", 17)) val kevinDoc = InsertOneModel(Person(4, "Kevin Moss", 22))
Importante
Al realizar una operación bulkWrite(), el InsertOneModel no puede insertar un documento con un _id ya existente en la colección. En este caso, el controlador lanza un MongoBulkWriteException.
El siguiente ejemplo intenta insertar dos documentos donde los valores _id son 1 y 3. Dado que ya existe un documento con un valor _id o 1 en la colección, la operación genera un error:
try { val bulkOperations = listOf( (InsertOneModel(Person(1, "James Smith", 13))), (InsertOneModel(Person(3, "Colin Samuels"))) ) val bulkWrite = collection.bulkWrite(bulkOperations) } catch (e: MongoBulkWriteException) { println("A MongoBulkWriteException occurred with the following message: " + e.message) }
A MongoBulkWriteException occurred with the following message: Bulk write operation error on server sample-shard-00-02.pw0q4.mongodb.net:27017. Write errors: [BulkWriteError{index=0, code=11000, message='E11000 duplicate key error collection: crudOps.bulkWrite index: _id_ dup key: { _id: 1 }', details={}}].
Para saber por qué el controlador no insertó el documento con el _id 3de, consulte la sección Orden de ejecución.
Para obtener más información sobre los métodos y clases mencionados en esta sección, consulte la documentación de la API InsertOneModel.
Operación de reemplazo
Para realizar una operación de reemplazo, cree un ReplaceOneModel especificando un filtro de consulta para el documento que desea reemplazar y el documento de reemplazo.
Importante
Al ejecutar un bulkWrite(), el ReplaceOneModel no puede realizar cambios que infrinjan las restricciones de índice único de la colección. Además, el modelo no realiza la operación de reemplazo si no hay coincidencias con el filtro de consulta.
Ejemplo
El siguiente ejemplo crea un ReplaceOneModel para reemplazar un documento donde el _id es 1 con un documento que contiene el campo adicional location:
val filter = Filters.eq("_id", 1) val insert = Person(1, "Celine Stork", location = "San Diego, CA") val doc = ReplaceOneModel(filter, insert)
Para obtener más información sobre los métodos y clases mencionados en esta sección, consulte los siguientes recursos:
Documentación de la API deReplaceOneModel
Explicación manualdel servidor de índices únicos
Operación de actualización
Para realizar una operación de actualización, cree un UpdateOneModel o un UpdateManyModel que especifique un filtro de consulta y un documento de actualización.
UpdateOneModel actualiza el primer documento que coincide con su filtro de consulta y UpdateManyModel actualiza todos los documentos que coinciden con su filtro de consulta.
Importante
Al ejecutar una consulta bulkWrite(), los tipos UpdateOneModel y UpdateManyModel no pueden realizar cambios que infrinjan las restricciones de índice único de la colección. Además, los modelos no realizan operaciones de actualización si no hay coincidencias con el filtro de consulta.
Ejemplo
El siguiente ejemplo crea un UpdateOneModel para incrementar el campo age en 1 en un documento donde el _id es 2:
val filter = Filters.eq("_id", 2) val update = Updates.inc(Person::age.name, 1) val doc = UpdateOneModel<Person>(filter, update)
Para obtener más información sobre los métodos y clases mencionados en esta sección, consulte los siguientes recursos:
UpdateOneModel API Documentation
Documentación de la APIUpdateManyModel
Explicación manual del servidorde índices únicos
Operación de eliminación
Para realizar una operación de eliminación, cree un DeleteOneModel o un DeleteManyModel que especifique un filtro de query para los documentos que desea eliminar.
DeleteOneModel elimina el primer documento que coincide con su filtro de consulta y DeleteManyModel elimina todos los documentos que coinciden con su filtro de consulta.
Importante
Al realizar una bulkWrite(), los tipos DeleteOneModel y DeleteManyModel no eliminan ningún documento si no hay coincidencias con el filtro de consulta.
Ejemplo
El siguiente ejemplo crea un DeleteOneModel para eliminar un documento donde el _id es 1 y un DeleteManyModel para eliminar documentos donde el valor age es menor que 30:
val deleteId1 = DeleteOneModel<Person>(Filters.eq("_id", 1)) val deleteAgeLt30 = DeleteManyModel<Person>(Filters.lt(Person::age.name, 30))
Para obtener más información sobre los métodos y clases mencionados en esta sección, consulte la siguiente documentación de API:
Orden de ejecución
El método bulkWrite() acepta un BulkWriteOptions opcional como segundo parámetro para especificar si desea ejecutar las operaciones masivas de forma ordenada o desordenada.
Ejecución ordenada
De forma predeterminada, el método bulkWrite() ejecuta las operaciones masivas en orden. Esto significa que las operaciones se ejecutan en el orden en que se añadieron a la lista hasta que se produzca algún error.
Ejemplo
El siguiente ejemplo realiza estas operaciones masivas:
Una operación de inserción para un documento donde
namees"Zaynab Omar"yagees37Una operación de reemplazo para un documento donde
_ides1con un nuevo documento que contiene el campolocationUna operación de actualización para un documento donde
_ides6para cambiar el camponameUna operación de eliminación para todos los documentos que tengan un valor
agemayor que50
val insertMdl = InsertOneModel(Person(6, "Zaynab Omar", 37)) val replaceMdl = ReplaceOneModel( Filters.eq("_id", 1), Person(1, "Sandy Kane", location = "Helena, MT") ) val updateMdl = UpdateOneModel<Person>( Filters.eq("_id", 6), Updates.set(Person::name.name, "Zaynab Hassan") ) val deleteMdl = DeleteManyModel<Person>(Filters.gt(Person::age.name, 50)) val bulkOperations = listOf( insertMdl, replaceMdl, updateMdl, deleteMdl ) val result = collection.bulkWrite(bulkOperations)
Después de ejecutar este ejemplo, su colección contendrá el siguiente documento:
{ "_id": 1, "name": "Sandy Kane", "location": "Helena, MT" } { "_id": 8, "name": "Shayla Ray", "age": 20 } { "_id": 6, "name": "Zaynab Hassan", "age": 37 }
Ejecución desordenada
También puede ejecutar operaciones masivas en cualquier orden pasando false al método ordered() de un objeto BulkWriteOptions. Esto significa que todas las operaciones de escritura se ejecutan independientemente de los errores. Si se produce algún error, el controlador lo informa al final.
El siguiente código muestra cómo ejecutar una operación masiva sin orden de ejecución:
val options = BulkWriteOptions().ordered(false) val unorderedResult = collection.bulkWrite(bulkOperations, options)
Nota
Las operaciones masivas desordenadas no garantizan el orden de ejecución. El orden puede variar según la forma en que se enumeran para optimizar el tiempo de ejecución.
En el ejemplo anterior, si el método bulkWrite() realizó la operación de inserción después de la operación de actualización, esta no produciría cambios porque el documento no existía en ese momento. La colección contendría entonces los siguientes documentos:
{ "_id": 1, "name": "Sandy Kane", "location": "Helena, MT" } { "_id": 8, "name": "Shayla Ray", "age": 20 } { "_id": 6, "name": "Zaynab Omar", "age": 37 }
Para obtener más información sobre los métodos y clases mencionados en esta sección, consulte la siguiente documentación de API:
Resumen
Para realizar una operación masiva, cree y pase una lista de WriteModel documentos al método bulkWrite().
Hay seis variaciones de WriteModel:
InsertOneModelReplaceOneModelUpdateOneModelUpdateManyModelDeleteOneModelDeleteManyModel
Hay dos formas de ejecutar el método bulkWrite():
Ordenado, donde el driver realiza las operaciones de guardado en orden hasta que ocurre algún error
Desordenado, donde el controlador realiza todas las operaciones de escritura en cualquier orden e informa cualquier error una vez completadas las operaciones