Eliminar datos en MongoDB

Tutorial de MongoDB con JavaCon este artículo se termina con las operaciones CRUD en MongoDB (Create, Read, Update, Delete). En el anterior artículo se mostró la actualización múltiple en MongoDB, mediante la cual, una operación de modificación se podía realizar sobre todos los documentos de una colección que cumpliesen el criterio de búsqueda. En este, se va a ver cómo eliminar datos en MongoDB, es decir, documentos, colecciones y bases de datos enteras.

Preparando el entorno

Antes de comenzar se van a crear varias colecciones con unos cuantos documentos para poder trabajar.
Primeramente se tiene que tener un servidor MongoDB arrancado, puedes ver como instalar uno en el artículo Instalación de MongoDB.
Sino se ha instalado MongoDB como servicio del sistema, se puede arrancar una instancia de esta forma:
$ mongod --smallfiles --oplogSize 50 --port 27017 --dbpath MONGODB/data/sh1/rs1 --fork --logpath MONGODB/logs/sh1/rs1/27017.log --logappend
Las opciones de arranque se verán más adelante en otro artículo específico para ello. A grosso modo estas opciones son para optimizar el sistema para trabajar con ficheros pequeños (–smallfiles –oplogSize 50), especificar el puesto de escucha (–port 27017), el directorio de almacenamiento de los datos (–dbpath MONGODB/data/sh1/rs1), el fichero de log para esta instancia (–logpath MONGODB/logs/sh1/rs1/27017.log) que será creado o se añadirá a uno existente (–logappend) y que este servidor se arranque en segundo plano (–fork).

Ahora se va a insertar en la base de datos “market” una serie de tiendas, especificadas mediante su id junto con los precios de determinados productos. Para esto se hace uso de JavaScript ya que la shell del cliente de mongo es un intérprete de dicho lenguaje.

$ mongo --port 27017
MongoDB shell version: 2.4.4
connecting to: 127.0.0.1:27017/test
>
> use market
switched to db market
> products = ['banana', 'apple', 'orange', 'almonds', 'coconuts', 'almonds'];
[ "banana", "apple", "orange", "almonds", "coconuts", "almonds" ]
> for (i = 0; i < 1000; i++) {
     prices = [];
     for (j = 0; j < products.length; j++) {
prices.push({'product':products[j],'price':Math.random()*100});
}
    record = {'shop_id':i, 'prices':prices};
    db.shops.insert(record);
}
y se verifica el contenido añadido:
> db.shops.count()
1000
> db.shops.findOne()
{
	"_id" : ObjectId("51bcad5a18c795b13ab50144"),
	"shop_id" : 0,
	"prices" : [
		{
			"product" : "banana",
			"price" : 29.685514490120113
		},
		{
			"product" : "apple",
			"price" : 32.161547942087054
		},
		{
			"product" : "orange",
			"price" : 46.369023667648435
		},
		{
			"product" : "almonds",
			"price" : 66.92518466152251
		},
		{
			"product" : "coconuts",
			"price" : 72.81906066928059
		},
		{
			"product" : "almonds",
			"price" : 23.056783759966493
		}
	]
}
>

Eliminar documentos en MongoDB

El borrado de documentos se puede realizar de forma sencilla y mediante un único comando para una determinada colección. Si se desea eliminar documentos de varias colecciones distintas para un mismo criterio entonces de se tendrá que realzar un script o usar lógica JavaScript para tal fin.
Para eliminar documentos de una colección se usa el metodo “remove“, el cual toma un primer parámetro de igual sintaxis que “find” para, de este modo, borrar los documentos que cumplan con dicho criterio de busqueda.

Como ejemplo se va a eliminar la tienda 500, es decir, el documento con la clave “shop_id” igual a “500”. Primero hay que comprobar que existe:

> db.shops.find({shop_id:500}).pretty()
{
	"_id" : ObjectId("51bcad5a18c795b13ab50338"),
	"shop_id" : 500,
	"prices" : [
		{
			"product" : "banana",
			"price" : 52.05784635618329
		},
		{
			"product" : "apple",
			"price" : 45.06270461715758
		},
		{
			"product" : "orange",
			"price" : 70.29240222182125
		},
		{
			"product" : "almonds",
			"price" : 92.52718964125961
		},
		{
			"product" : "coconuts",
			"price" : 0.0030659371986985207
		},
		{
			"product" : "almonds",
			"price" : 15.94509647693485
		}
	]
}
>

Y se procede al borrado del documento:

> db.shops.remove({'shop_id':500})

El siguiente paso es obvio, verificar la eliminación del documento en MongoDB:

> db.shops.find({'shop_id':500}).pretty()
> db.shops.count()
999

Es muy importante saber que sino se le pasa ningún parámetro borraría absolutamente todos los documentos pertenecientes a la colección (uno a uno y con los mismos problemas de concurrencia que la actualización múltiple).

Para ver algunos ejemplos más, se van a borrar todos las tiendas que posean algún producto con un precio mayor de 90:

> db.shops.find({ 'prices.price': {$gt: 90} }).count()
442
> db.shops.remove({ 'prices.price': {$gt: 90} })
> db.shops.find({ 'prices.price': {$gt: 90} }).count()
0
> db.shops.find().count()
557
>

y las tiendas comprendidas entre el 100 y 200:

> db.shops.find({ $and: [ {'shop_id': {$gte: 100}}, {'shop_id': {$lte: 200}}  ] }).count()
59
> db.shops.remove({ $and: [ {'shop_id': {$gte: 100}}, {'shop_id': {$lte: 200}}  ] })
> db.shops.find({ $and: [ {'shop_id': {$gte: 100}}, {'shop_id': {$lte: 200}}  ] }).count()
0
> db.shops.find().count()
498

Eliminar colecciones en MongoDB

Hay varios métodos para borrar todos los documentos de una colección en MongoDB.

Una de ellas es, precisamente, borrar todos documentos de una colección, para ello se usa el método “remove” sin argumentos o con un documento vacío como criterio de búsqueda.

> db.shops.remove()
> db.shops.find().count()
0
>

> products = ['banana', 'apple', 'orange', 'almonds', 'coconuts', 'almonds'];
[ "banana", "apple", "orange", "almonds", "coconuts", "almonds" ]
> for (i = 0; i < 1000; i++) {      prices = [];      for (j = 0; j < products.length; j++) {  prices.push({'product':products[j],'price':Math.random()*100});      }      record = {'shop_id':i, 'prices':prices};      db.shops.insert(record);  }
> db.shops.find().count()
1000

> db.shops.remove({})
> db.shops.find().count()
0

Este método no es muy eficiente para borrar colecciones enteras, sobre todo si tienen gran cantidad de documentos, ya que el borrado se hace de de documento en documento. Por ello, se usa el método “drop” el cual libera la colección de su uso y borra los documentos posteriormente. Para la aplicación cliente el borrado de la colección es inmediato ya que no tendrá acceso a esos documentos aunque realmente no hayan sido borrados aún.

> products = ['banana', 'apple', 'orange', 'almonds', 'coconuts', 'almonds'];
[ "banana", "apple", "orange", "almonds", "coconuts", "almonds" ]
> for (i = 0; i < 1000; i++) {      prices = [];      for (j = 0; j < products.length; j++) {  prices.push({'product':products[j],'price':Math.random()*100});      }      record = {'shop_id':i, 'prices':prices};      db.shops.insert(record);  }

> db.shops.drop()
true
> db.shops.find().count()
0

Eliminar bases de datos en MongoDB

Para eliminar bases de datos en MongoDB se usa el método “dropDatabase” del documento “db” (no a nivel de colección). Este método se ejecuta sin parámetros para borra la base de datos, al completo, que se esté usando.

Como ejemplo, se van a crear varias colecciones (insertando un documento) en una base de datos cualquiera para después ser borradas:

> use market
switched to db market
> show collections
> 
> db.coll1.insert({_id:"Happy"})
> db.coll2.insert({_id:"Happy Minds!"})
> db.coll3.insert({_id:"Happy Minds! Software"})
> 
> show collections
coll1
coll2
coll3
system.indexes

> db.dropDatabase()
{ "dropped" : "market", "ok" : 1 }
> show collections
>

Una base de datos borrada no afecta al uso posterior que puedan hacer las aplicaciones clientes ya que, si después de borrada se insertan documentos volvería a estar operativa salvo que sin los datos anteriores que fueron eliminados.

Conclusión

Como se puede observar con los ejemplos dispuestos en este artículo del tutorial de MongoDB con Java, la eliminación de datos en MongoDB es muy sencilla a la vez que peligrosa ya que, un descuido como invocar a un “remove” sin especificar un filtro de búsqueda, eliminaría una colección de datos entera. Es por ello que se debe usar con mucha cautela y, al igual que se ha hecho en este tutorial, realizar antes “find” y “count” para ver que es correcto y coherente lo que se desea eliminar.

Happy Minds!

Share on FacebookTweet about this on TwitterShare on LinkedInShare on RedditShare on Google+Digg thisShare on TumblrPin on PinterestBuffer this pagePrint this pageEmail this to someone