MongoDB: la vida cambia, tus datos también. Eliminando elementos de un array y documentos completos

Continuamos con la actualización de datos en MongoDB. En el anterior artículo, expliqué como se podían actualizar subdocumentos y añadir elementos a un campo de tipo array. Con los arrays podemos usar un puñado de operadores interesantes como $push, $addToSet, $each o $slice.

Pero de nada sirve saber cómo se añaden elementos a un array, si no sabemos como eliminarlos. Y es lo que vamos a ver en este artículo.

Además, veremos como realizar la operación de modificación de datos que nos queda por conocer: la eliminación de documentos. Vamos a ello.

Quitando elementos de un array

Quitar elementos de un array, es bastante parecido a añadirlos. Supongamos que tenemos un documento con el siguiente esquema:

{
    "_id" : 2,
    "cast" : [ 
        "Morgan Freeman", 
        "Tim Robins", 
        "Bob Gunton", 
        "Clancy Brown"
    ],
    "info" : {
        "director" : "Frank Darabont",
        "writer" : "Stephen King"
    },
    "title" : "The Shawshank Redemption",
    "year" : 1994,
    "votes": [4,8,8,7,5,10,9,7,7,9,13,10,13,3]
}

Si queremos eliminar elementos del array, podemos utilizar los operadores $pull y $pullAll. Por ejemplo, vemos que se han producido errores al insertar elementos en el campo votes. El campo representa los votos que recibe una película por parte de cada usuario. Los valores permitidos van de 1 a 10, pero por error se han añadido elementos con un valor de 13. Para eliminarlos bastaría con ejecutar la siguiente sentencia:

db.genbetadev.update(
 {"_id" : 2},
 {$pull : {"votes" : 13}}
);

Y el resultado sería algo parecido a esto:

{
"_id" : 2,
"cast" : [ 
    "Morgan Freeman", 
    "Tim Robins", 
    "Bob Gunton", 
    "Clancy Brown"
],
"info" : {
    "director" : "Frank Darabont",
    "writer" : "Stephen King"
},
"title" : "The Shawshank Redemption",
"votes" : [4,8,8,7,5,10,9,7,7,9,10,3],
"year" : 1994
}

Usando $pull se eliminan todos los elementos cuyo valor es de 13. Si queremos eliminar distintos valores en la misma consulta, haremos una operación similar pero utilizando $pullAll. Este operador acepta un array como parámetro, por lo que es ideal para expresar varios valores a localizar y eliminar del array.

Eliminando elementos con $pop

Otra manera de eliminar elementos de un array, es haciendo que MongoDB elimine siempre el primer o último elemento de la lista. Para eso utilizamos el operador $pop.

Supongamos que tenemos un documento como este:

{
    "_id": "rubenfa",
    "favorites":
    [
      "Star Wars",
      "The Shawshank Redemption", 
      "Training Day", 
      "The Incredibles", 
      "The Departed"
    ]
}

El operador $pop recibe un solo parámetro, que podrá ser -1 o 1. Si le pasamos 1 borrará el último elemento del array. Con -1 borrará el primer elemento del array. Por ejemplo:

db.genbetadev.update(
{"_id" : "rubenfa"},
{$pop:{"favorites" : -1}}
);

Como le estamos pasando un -1, la sentencia eliminará "Star Wars" del array. Si cambiáramos el -1 por un 1, borraría "The Departed". Si ejecutamos la sentencia varias veces, los elementos se irán borrando hasta que el array quede vacío.

{
    "_id" : "rubenfa",
    "favorites" : []
}

Modificaciones posicionales de un array

En ocasiones, lo que necesitamos es modificar un elemento del array en base a su posición. Aquí tenemos dos opciones: modificar un elemento en una posición concreta o modificar un elemento del que no conocemos su posición exacta, pero que podemos localizar con una consulta.

Aprovechándonos de la posibilidad de que con JavaScript podemos acceder a un array a través de su índice, seremos capaces de acceder a un elemento concreto de nuestros campos de tipo array. Por ejemplo myArray[0] accede a la primera posición del array, myArray[1] a la segunda, y así sucesivamente. Por ejemplo, si imaginemos el siguiente documento:

{
    "_id" : "rubenfa",
    "top5" : [ 
        {
            "title" : "The Departed",
            "vote" : 7.5
        }, 
        {
            "title" : "The Shawshank Redemption",
            "vote" : 8
        }, 
        {
            "title" : "The Incredibles",
            "vote" : 8
        }, 
        {
            "title" : "Matrix",
            "vote" : 8
        }, 
        {
            "title" : "Star Wars",
            "vote" : 9
        }
    ]
}

En este caso, el documento almacena las 5 películas mejor valoradas por un usuario. Si hacemos lo siguiente:

db.genbetadev.update(
{"_id" : "rubenfa"},
{$inc: {"top5.0.vote" : 1}}
);

Estamos diciendo, que queremos incrementar en 1 el campo "vote" del primer elemento del array. Usando otro índice (top.1.vote o top.2.vote), podríamos modificar cualquier otro elemento del array.

Si no sabemos la posición exacta de un elemento, pero sabemos que podemos encontrarlo con una consulta, podemos utilizar el operador posicional $. Veamos un ejemplo sobre el mismo documento del ejemplo anterior:

db.genbetadev.update(
{
 "_id" : "rubenfa",
 "top5.title" : "Matrix"
},
 {$inc : {"top5.$.vote" : -1}}
);

Realizamos una consulta en la que se busca un documento con _id:"rubenfa" y cuyo campo top5 (de tipo array) contenga una película con el título "Matrix". En el segundo parámetro de la consulta update, es decir en el objeto JSON que representa la modificación de datos a realizar, utilizamos el operador posicional $. Este operador hace que el primer elemento del array que cumpla la condición, es decir que contenga el título "Matrix", sea modificado. En este caso reduciendo en 1 el campo vote (al que he accedido haciendo uso de dot notation).

Es importante destacar que para que este operador funcione, el campo array debe aparecer en la consulta, y que además sólo se modificará el primer elemento encontrado.

Borrando documentos

Ya hemos visto como hacer inserciones de documentos, como actualizarlos -incluyendo subdocumentos y arrays - pero aun nos queda ver como eliminar documentos. Esta operación la realizaremos con el comando remove. Cuando remove no recibe parámetros, elimina todos los documentos de una colección. Ojo, la consulta no elimina la colección. Solo su contenido. Para eliminar una colección deberemos usar drop, al más puro estilo SQL.

Si queremos eliminar un documento en concreto, deberemos pasar un objeto JSON a la función remove para identificar los documentos que queremos eliminar. Por ejemplo:

db.genbetadev.remove({"_id" : "rubenfa"});

La sentencia borrará todos los documentos cuyo _id sea "rubenfa". En este caso, y al tratarse de un campo _id, solo se encontrará un documento. Si la consulta encontrase más documentos, todos serían borrados.

El comando remove no se puede deshacer, y una vez eliminado un documento, se borra para siempre. Así que hay que tener cuidado con lo que hacemos.

Bueno, ahora ya sabemos como podemos insertar, actualizar y eliminar documentos. En próximos artículos veremos como realizar consultas más complejas, que podremos usar para buscar documentos o para filtrar aquellos que haya que modificar o eliminar.

En GenbetaDev | MongoDB: qué es, cómo funciona y cuándo podemos usarlo (o no), MongoDB: empezando por el principio. Insertando datos Imagen | Seth Anderson

Ver todos los comentarios en https://www.genbeta.com

VER 0 Comentario

Portada de Genbeta