MongoDB es una base de datos NoSQL multiplataforma, orientada a documentos y de código abierto, escrita en C++. Además, MongoDB proporciona alto rendimiento, alta disponibilidad y escalado automático.
Para actualizar los documentos en MongoDB, podemos usar diferentes métodos como updateOne, findOneAndUpdate, etc. Además, MongoDB proporciona varios operadores para los métodos de actualización.
En este tutorial, analizaremos diferentes enfoques para realizar operaciones de actualización en MongoDB. Para cada enfoque, primero discutiremos la consulta de mongo shell y luego su implementación en Java.
Configuración de la base de datos
Antes de pasar a las consultas de actualización, primero creemos una base de datos, colegio y una colección de muestra, estudiante:
use colegio;
db.createCollection(estudiante);
Como ilustración, agreguemos algunos documentos a la colección estudiante usando la consulta insertMany:
db.estudiante.insertMany([
{
"id": 8764,
"nombre": "Paul Starc",
"direccion": "Hostel 1",
"año": 16,
"roll_no":199406
},
{
"id": 8765,
"nombre": "Andrew Boult",
"direccion": "Hostel 2",
"año": 18,
"roll_no":199408
}
]);
En una inserción exitosa, obtendremos un JSON con reconocido: verdadero:
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("621b078485e943405d04b557"),
ObjectId("621b078485e943405d04b558")
]
}
Ahora profundicemos en las diferentes formas de actualizar los documentos en MongoDB.
Usando el método updateOne
Se puede realizar una operación de actualización en MongoDB agregando un nuevo campo, eliminando un campo o actualizando un campo existente. El método updateOne actualiza un solo documento en una colección según el filtro de consulta aplicado. Primero encuentra el documento que coincide con el filtro y luego actualiza los campos especificados.
Además, podemos usar diferentes operadores como $set, $unset, $inc, etc., con el método de actualización.
Para demostrarlo, analicemos la consulta para actualizar un solo documento de una colección:
db.estudiante.updateOne(
{
"nombre" : "Edward Elric"
},
{
$set: {
"direccion" : "Amestris"
}
}
);
Obtendremos una salida similar a la que se muestra a continuación:
{
"acknowledged":true,
"matchedCount":1,
"modifiedCount":1
}
Veamos ahora el código del controlador Java de la consulta updateOne anterior:
UpdateResult updateResult = collection.updateOne(Filters.eq("nombre", "Edward Elric"),
Updates.set("address", "Amestris"));
Aquí, en primer lugar, hemos utilizado el campo nombre para filtrar los documentos. Luego actualizamos la dirección del documento con nombre “Edward Elric”.
Usando el método updateMany
El método updateMany actualiza todos los documentos en las colecciones de MongoDB que coinciden con el filtro dado. Uno de los beneficios de usar updateMany es que podemos actualizar varios documentos sin perder los campos de los documentos antiguos.
Veamos la consulta de shell de MongoDB usando el método updateMany:
db.estudiante.updateMany(
{
edad: {
$lt: 20
}
},
{
$set:{
"revisar" : true
}
}
);
El comando anterior devolverá el siguiente resultado:
{
"acknowledged":true,
"matchedCount":2,
"modifiedCount":2
}
Aquí, matchedCount contiene el número de documentos coincidentes, mientras que modifiedCount contiene el número de documentos modificados.
Ahora veamos el código del controlador de Java usando el método updateMany:
UpdateResult updateResult = collection.updateMany(Filters.lt("edad", 20), Updates.set("revisar", true));
Aquí, se filtrarán todos los documentos con menos de 20 años y el campo revisar se establecerá en verdadero.
Usando el método replaceOne
El método replaceOne de MongoDB reemplaza todo el documento. Uno de los inconvenientes de replaceOne es que todos los campos antiguos serán reemplazados por los nuevos campos, y los campos antiguos también se perderán:
db.estudiante.replaceOne(
{
"id": 8764
},
{
"id": 8764,
"nombre": "Alphonse Elric",
"direccion": "Amestris",
"edad": 18,
"roll_no":199406
}
);
En este caso, obtendremos el siguiente resultado:
{
"acknowledged":true,
"matchedCount":1,
"modifiedCount":1
}
Si no se encuentran coincidencias, la operación devuelve matchedCount como 0:
{
"acknowledged":true,
"matchedCount":0,
"modifiedCount":0
}
Escribamos el código del controlador de Java correspondiente usando el método replaceOne:
Document replaceDocument = new Document();
replaceDocument
.append("id", 8764)
.append("nombre", "Alphonse Elric")
.append("direccion", "Amestris")
.append("edad",18)
.append("roll_no", 199406);
UpdateResult updateResult = collection.replaceOne(Filters.eq("id", 8764), replaceDocument);
En el código anterior, hemos creado un documento por el cual se reemplazará el documento anterior. El documento con student_id 8764 será reemplazado por el documento recién creado.
Usando el método findOneAndReplace
El método findOneAndReplace es uno de los métodos de actualización avanzados proporcionados por MongoDB y reemplaza el primer documento coincidente según los criterios de selección dados. De forma predeterminada, este método devuelve el documento original. Podemos usar diferentes opciones de findOneAndReplace para ordenar y proyectar documentos si es necesario.
En resumen, findOneAndReplace reemplaza el primer documento coincidente de la colección en función del filtro aplicado:
db.estudiante.findOneAndReplace(
{
"id" : {
$eq : 8764
}
},
{
"id" : 8764,
"nombre" : "Paul Starc",
"direccion": "Hostel 2",
"edad": 18,
"roll_no":199406
},
{
returnNewDocument: false
}
);
Esta consulta devolverá el siguiente documento:
{
"id":8764,
"nombre":"Paul Starc",
"direccion":"Hostel 1",
"edad":16,
"roll_no":199406
}
Si establecemos returnNewDocument en verdadero, la operación devolvería el documento reemplazado en su lugar:
{
"id":8764,
"nombre":"Paul Starc",
"direccion":"Hostel 2",
"edad":18,
"roll_no":199406
}
Ahora usemos el método findOneAndReplace para proyectar los campos student_id y age en el documento devuelto:
db.estudiante.findOneAndReplace(
{
"id" : {
$eq : 8764
}
},
{
"id" : 8764,
"nombre" : "Paul Starc",
"direccion": "Hostel 2",
"edad": 18,
"roll_no":199406
},
{
projection: {
"_id" : 0,
"id":1,
"edad" : 1
}
}
);
El resultado de la consulta anterior solo contendrá los campos proyectados:
{
"id":"8764",
"edad":16
}
El código del controlador Java de la consulta anterior con varias opciones de findOneAndReplace:
Document replaceDocument = new Document();
replaceDocument
.append("id", 8764)
.append("nombre", "Paul Starc")
.append("direccion", "Hostel 2")
.append("edad", 18)
.append("roll_no", 199406);
Document sort = new Document("roll_no", 1);
Document projection = new Document("_id", 0).append("id", 1).append("direccion", 1);
Document resultDocument = collection.findOneAndReplace(
Filters.eq("id", 8764),
replaceDocument,
new FindOneAndReplaceOptions().upsert(true).sort(sort).projection(projection).returnDocument(ReturnDocument.AFTER));
En la consulta anterior, el método findOneAndReplace ordenará primero los documentos en orden ascendente según roll_no, y el documento recién creado reemplaza el documento con student_id “8764”.
Usando el método findOneAndUpdate
El método findOneAndUpdate actualiza el primer documento coincidente de la colección. Si más de un documento coincide con los criterios de selección, solo se actualiza el primer documento coincidente. Cuando actualizamos el documento, el valor del campo _id permanece sin cambios:
db.estudiante.findOneAndUpdate(
{
"id" : 8764
},
{
$inc : {
"roll_no" : 5
}
},
{
sort: {
"roll_no" : 1
},
projection: {
"_id" : 0,
"id":1,
"direccion" : 1
}
}
);
El resultado de la consulta solo contendrá el ID de estudiante y la dirección del documento anterior:
{
"student_id":8764,
"address":"Hostel 1"
}
El código del controlador Java de la consulta anterior, utilizando diferentes opciones de findOneAndUpdate, es el siguiente:
Document sort = new Document("roll_no", 1);
Document projection = new Document("_id", 0).append("id", 1).append("direccion", 1);
Document resultDocument = collection.findOneAndUpdate(
Filters.eq("id", 8764),
Updates.inc("roll_no", 5),
new FindOneAndUpdateOptions().sort(sort).projection(projection).returnDocument(ReturnDocument.BEFORE));
En este caso, el método findOneAndUpdate ordenará primero el documento en orden ascendente según roll_no. La consulta anterior incrementa el roll_no en 5 y luego devuelve los campos student_id y address.
Conclusión
En este artículo, hemos visto varias formas de actualizar los documentos en MongoDB. Primero, analizamos la consulta de shell de MongoDB y luego discutimos el código del controlador de Java correspondiente.