Curso certificación mongodb

[2.2] Dado un escenario de actualización donde se proporciona un documento entero, identificar el resultado (output) y como ha cambiado el estado de la base de datos

Dentro de la segunda sección de la certificación, la competencia de crear y actualizar vienen a tener el mayor peso. De cara a dominar la actualización de documentos, empezaremos esta sección con la función replaceOne({},{},{})

Contexto teórico

Cuando hablamos de los operadores de actualización (update), usamos instrucciones que modifican el contenido de un documento en formato BSON, por ejemplo, al añadirle un campo, eliminarlo incrementar un valor. Cuando queremos substituir un documento, por otro, a través de un criterio de búsqueda (filtro) utilizaremos el método replaceOne.

Esta función sigue la siguiente estructura:

db.collection.replaceOne(

   <filter>,

   <replacement>,

   {

     upsert: <boolean>,

     writeConcern: <document>,

     collation: <document>,

     hint: <document|string>

   }

Es importante remarcar que en el caso de que el filtro no indique solamente un resultado, entonces, se actualizará el primero siguiendo el orden dentro de la colección.

El segundo parámetro, será el BSON con el que substituiremos la colección que cumple el criterio de búsqueda.

El tercer parámetro es opcional, y se escapa de la certificación saberlo usar correctamente.

El resultado que obtendremos es un documento con los siguientes campos:

  • El booleano acknowledged valdrá true cuando el operador se ejecuta con writeConcern o false cuando writeConcern esté desactivado.
  • matchedCount contendrá el número de documentos que cumplen el criterio de búsqueda.
  • modifiedCount contiene el número de documentos modificados, que en este caso, solo podrá ser 0 o 1.
  • upsertedCount dice cuantos documentos se han upserteado. El concepto upserteado significa, que si el criterio de filtrado no trae ningún resultado, entonces, el documento se creará nuevo en la colección.

Secuencia: crear documentos sobre una base de datos de prueba


Crea la base de datos y la colección

Desde la herramienta Compass, una vez iniciada la sesión, debes apretar en el botón (+) en la línea que pone Databases. En nuestro caso la llamaremos «certification». Una vez creada, al pasar el botón por encima del nombre de la base de datos, volverá a aparecer un botón (+). Entonces crear una colección que se llame «mycollection». En el caso de que ya exista una colección con ese nombre, puedes borrarla desde la UI o desde MongoSh con "db.mycollection.deleteMany({})"

Insertar un primer documento

Ejecuta el comando

db.mycollection.insertOne({_id: 1, country: "ESP"})

Realizar el remplazo del documento

Ejecuta el comando

db.mycollection.replaceOne({ _id: 1 }, { name: "Bob", age: 30 })

El resultado es:

{  

acknowledged: true, 

insertedId: null, 

matchedCount: 1, 

modifiedCount: 1, 

upsertedCount: 0

}

A través de Compass podemos ver que ahora tenemos una colección con {_id:1, name: "Bob", age: 30}, es decir, el valor original ha sido remplazado.

Remplazar un documento que no existe

Ahora vamos a remplazar el documento con _id:2, que sabemos que no existe

db.mycollection.replaceOne({ _id: 2}, { name: "Bob", age: 30 })

Con este resultado.

{  

acknowledged: true, 

insertedId: null, 

matchedCount: 0, 

modifiedCount: 0, 

upsertedCount: 0

}

Como por defecto el upsert está desactivado, no se creará un documento nuevo cuando este no se encuentro en la colección.

Si refrescamos Compass, veremos que no se ha creado el segundo documento.

Remplazar con la opción de upsert activada

Vamos a realizar la misma operación que en el paso anterior, pero activando la opción de upsert.

db.mycollection.replaceOne({ _id: 2}, { name: "Bob", age: 30 },{upsert: true})

Con este resultado.

{  

acknowledged: true, 

insertedId: 2, 

matchedCount: 0, 

modifiedCount: 0, 

upsertedCount: 1

}

Como indica el documento, el insertId coincide con el de nuestro comando, mientras que también se ve que no se ha encontrado nada a través del filtro, y que el documento se creado porque

Pregunta 1


Dado los siguientes documentos

{_id:1, a: "one", b: "four"}

{_id:2, a: "two", b: "four"}

{_id:3, a: "three", b: "four", c: "three"}

Cuando se ejecuta el siguiente comando:

db.coll.replaceOne({}, {a: "ten", b: "five"})

Cual es el resultado?

A. {_id:1, a: "ten", b: "five"} {_id:2, a: "ten", b: "five"} {_id:3, a: "ten", b: "five"}

B. {_id:1, a: "ten", b: "five"} {_id:2, a: "two", b: "four"} {_id:3, a: "three", b: "four", c: "three"}

C. {_id:1, a: "ten", b: "five"} {_id:2, a: "ten", b: "five"} {_id:3, a: "ten", b: "five", c: "three"}

D. {_id:1, a: "one", b: "four"} {_id:2, a: "two", b: "four"} {_id:3, a: "three", b: "four", c: "three"}

La respuesta es la A. Cuando replaceOne se utiliza con un primer parámetro vacío, le estamos indicando que no filtre, en este caso, devolverá tres documentos, y por orden de aparición, el documento con _id:1 es el primer en orden, y por tanto el que se seleccionará. El resto de documentos permanecerá igual

Conclusión

replaceOne es el primer operador que estudiamos para realizar las actualizaciones. Su sintaxis es más sencilla que el update, ya que evitamos usar operadores atómicos como $set, y el documento es remplazado completamente. También es una función correcta para introducir el concepto de filtro, que ya vio en los artículos referentes a lecturas. El otro concepto clave y que ya se revisará en los siguientes artículos es el de upsert, y que permite, cuando está habilitado, insertar documentos cuando estos no existen, y que por tanto, no se pueden actualizar.