Introducción a MongoDB. Ejemplos de consultas en documentos.

En este proyecto se crearán y definirán consultas en MOngoDb a una hipotética base de datos para una app de mensajería instantánea. Se proporcionarán las sentencias para el shell de MongoDB y los resultados que se obtienen en cada uno de los apartados.

Encontrar en la collection Usuarios_Individuales los usuarios que proceden de Madrid y que tienen una edad entre 20 y 40 años sin incluir aquellos que tengan 20 o 40. Mostrarlos ordenados descendentemente por edad, listando solo su email y su edad.

La consulta realizada es la siguiente:

 db.getCollection('Usuarios_Individuales').find({'Ciudad':'Madrid','Edad':{ $gt: 20, $lt:40}},
 { 'Email':1,'Edad':1,'_id': 0}).sort({'Edad':-1}

Con el siguiente resultado

{ 'Email' : 'plopezternasco@hotmail.es', 'Edad' : 38 }
{ 'Email' : 'ilopezmena@gmail.es', 'Edad' : 35 }
{ 'Email' : 'afraguasazul@gmail.es', 'Edad' : 35 }

Lo más interesante de esta consulta, es la utilización de $gt: 20 y $lt:40. Estas dos etiquetas nos permiten encontrar aquellos usuarios que tengan una edad entre 20 y 40 años sin incluir aquellos que tengan 20 o 40.

Listar el nombre de los usuarios bloqueadores de la collection Bloqueos que han creado un bloqueo entre las 9:25 y las 10.

La consulta tiene una dificultad añadida con respecto la anterior. En este caso vamos a buscar en un subdocumento, por lo tanto, es necesario utilizar $elemMatch para obtener el resultado deseado.

 db.Usuarios_bloqueadores.find (
 {
 $or: [
 {
 'Bloqueos':{$elemMatch: { 'Hora_bloqueo.Hora':  10, 'Hora_bloqueo.Minutos': 0 }}}
 ,
 {
 'Bloqueos':{$elemMatch: { 'Hora_bloqueo.Hora':  9, 'Hora_bloqueo.Minutos': {$gte: 25 }}}
 }
 ]
 }
 , {Nombre:1, Apellidos:1,_id:0, 'Bloqueos.Hora_bloqueo':1 } ).pretty()

 db.Usuarios_bloqueadores.find (
 {
 $or: [
 {
 'Bloqueos':{$elemMatch: { 'Hora_bloqueo.Hora':  10, 'Hora_bloqueo.Minutos': 0 }}}
 ,
 {
 'Bloqueos':{$elemMatch: { 'Hora_bloqueo.Hora':  9, 'Hora_bloqueo.Minutos': {$gte: 25 }}}
 }
 ]
 }
 , {Nombre:1, Apellidos:1,_id:0 } ).pretty()

Los resultados con la comprobación de la hora.
{
	"Nombre" : "Cristina",
	"Apellidos" : "Garcia Abril",
	"Bloqueos" : [
		{
			"Hora_bloqueo" : {
				"Hora" : 4,
				"Minutos" : 44,
				"Segundos" : 6
			}
		},
		{
			"Hora_bloqueo" : {
				"Hora" : 9,
				"Minutos" : 28,
				"Segundos" : 33
			}
		}
	]
}
{
	"Nombre" : "Gabriel",
	"Apellidos" : "Regalado Martin",
	"Bloqueos" : [
		{
			"Hora_bloqueo" : {
				"Hora" : 9,
				"Minutos" : 52,
				"Segundos" : 43
			}
		},
		{
			"Hora_bloqueo" : {
				"Hora" : 15,
				"Minutos" : 12,
				"Segundos" : 47
			}
		}
	]
}
Sin la comprobación:
{ "Nombre" : "Cristina", "Apellidos" : "Garcia Abril" }
{ "Nombre" : "Gabriel", "Apellidos":"Regalado Martin"}

Encontrar cuantos documentos de la collection Grupos_usuarios tienen:

  • Identificador (G-nnnn) que termina en un número par, o sea nnnn es par,
  • Id_propietario (U-mmmm) que termina en un número par, o sea mmmm es par

En esta consulta utilizaré $regex para saber si es o no es un número par.

db.Grupos_usuarios.find( {
'Identificador' : {$regex: "G-.*\.[02468]$" }, 'Id_propietario' : {$regex: "U-.*\.[02468]$" } },{'Identificador':1, 'Id_propietario':1,_id:0 }).pretty()

 db.Grupos_usuarios.find( {
'Identificador' : {$regex: "G-.*\.[02468]$" }, 'Id_propietario' : {$regex: "U-.*\.[02468]$" } },{'Identificador':1, 'Id_propietario':1,_id:0 }).count()

Los resultados han sido:

{ "Identificador" : "G-3456", "Id_propietario" : "U-3490" }
{ "Identificador" : "G-3458", "Id_propietario" : "U-3484" }
{ "Identificador" : "G-3460", "Id_propietario" : "U-3462" }
{ "Identificador" : "G-3466", "Id_propietario" : "U-3480" }
{ "Identificador" : "G-3468", "Id_propietario" : "U-3456" }
{ "Identificador" : "G-3470", "Id_propietario" : "U-3464" }
{ "Identificador" : "G-3482", "Id_propietario" : "U-3484" }
{ "Identificador" : "G-3484", "Id_propietario" : "U-3480" }
{ "Identificador" : "G-3486", "Id_propietario" : "U-3490" }
{ "Identificador" : "G-3488", "Id_propietario" : "U-3480" }
{ "Identificador" : "G-3494", "Id_propietario" : "U-3480" }

El resultado del segundo comando es: 11

Listar Nombre y Apellidos de los usuarios en la collection Usuarios_desbloqueadores que han creado al menos un desbloqueo en el mes de Octubre, entre las 10 y las 15 horas (15 incluidas)

db.Usuarios_desbloqueadores.find (
{
'Desbloqueos':
{$elemMatch:
 {'Fecha_desbloqueo.Mes':  10 , 'Hora_desbloqueo.Hora': {$gt:10 , $lte:15} }
}
}, {Nombre:1, Email:1, 'Desbloqueos.Hora_desbloqueo.Hora':1 , 'Desbloqueos.Fecha_desbloqueo.Mes':1 ,_id:0 } ).pretty()

db.Usuarios_desbloqueadores.find (
{
'Desbloqueos':
{$elemMatch:
 {'Fecha_desbloqueo.Mes':  10 , 'Hora_desbloqueo.Hora': {$gt:10 , $lte:15} }
}
}, {Nombre:1, Apellidos:1 ,_id:0 } ).pretty()

Los resultados han sido:

{
	"Nombre" : "Juan",
	"Email" : "jsanzrobles@hotmail.es",
	"Desbloqueos" : [
		{
			"Fecha_desbloqueo" : {
				"Mes" : 10
			},
			"Hora_desbloqueo" : {
				"Hora" : 13
			}
		},
		{
			"Fecha_desbloqueo" : {
				"Mes" : 11
			},
			"Hora_desbloqueo" : {
				"Hora" : 19
			}
		}
	]
}
{
	"Nombre" : "Barbara",
	"Email" : "bbellovalero@gmail.es",
	"Desbloqueos" : [
		{
			"Fecha_desbloqueo" : {
				"Mes" : 5
			},
			"Hora_desbloqueo" : {
				"Hora" : 14
			}
		},
		{
			"Fecha_desbloqueo" : {
				"Mes" : 10
			},
			"Hora_desbloqueo" : {
				"Hora" : 14
			}
		}
	]
}

Siguiendo las peticiones del enunciado, obtengo:

{ "Nombre" : "Juan", "Apellidos" : "Sanz Robles" }
{ "Nombre" : "Barbara", "Apellidos" : "Bello Valero" }

Para la collection Grupos_usuarios, encontrar las ciudades que tienen más de 15 miembros con más de 35 años. Listar las ciudades encontradas por número descendente de miembros.

En este caso he utilizado aggregate para resolver el requerimiento. De esta forma he agrupado la información y seleccionado aquella que me ha interesado. Para seleccionar los subdocumentos deseados he utilizado la etiqueta $match y para agrupar $group.

db.Grupos_usuarios.aggregate([
  { "$unwind": "$Miembros" },
{$match: {'Miembros.Edad': {$gt: 35}}},
  { "$group": {
    "_id": "$Miembros.Ciudad",
    "count": { "$sum": 1 }
  }},
  { $match: { count: { $gt: 15} } },
     { $sort : { count : -1 } }

])

{ "_id" : "Valencia", "count" : 21 }
{ "_id" : "Zaragoza", "count" : 17 }