MongoDB – Querying II

En entradas anteriores se presentaron las características generales de MongoDB así como una introducción sobre cómo se realizan las consultas, donde pudimos ver la insercción, eliminación de documentos y consultas sobre los mismos. En esta entrada vamos a analizar consultas más avanzadas sobre tipos complejos de datos mediante el uso de código JavaScript. Además, expondremos el uso de índices para mejorar la eficiencia en las consultas.

Consultas a tipos complejos de datos con MongoDB

Anteriormente se mostró cómo hacer consultas sobre tipos de datos simples, pero MongoDB puede tener datos de tipos más complejos como arrays o documentos embebidos los cuales pueden ser accesibles en las consultas.

Consultas sobre arrays

La primera aproximación para realizar búsquedas dentro de un array es utilizar la función find de la misma forma que se utiliza para tipos de datos simples.

Teniendo el siguiente documento: {“lista” : [“Juan”, “Pepe”, “Pedro”]}

empleados.find({"lista": "Pepe"})

El código anterior devolverá el documento, ya que es posible encontrar el valor buscado en cualquiera de los componentes de la lista.

En caso de querer buscar aquellos componentes donde un conjunto de valores debe ser encontrado en una lista, es posible hacerlo a través de la función $all. Esta función no comprueba el orden de búsqueda y solo comprueba que los elementos buscados existan en el array.

empleados.find({"lista": {"$all": ["Pepe", "Juan"]}})

Es posible buscar por posiciones específicas del array, accediendo a la posición del array mediante un “.”.

empleados.find({"lista.0": "Juan"})

Además de $all, otro operador condicional para la realización de búsquedas es $size. Mediante este operador es posible buscar documentos comprobando el tamaño del array:

empleados.find({"lista": {"$size":  4}})

Consulta sobre documentos embebidos

Una de las mejores características de MongoDB, y que lo diferencia frente a otras bases de datos, es su capacidad para almacenar documentos embebidos.

Un ejemplo de consulta sobre un documento embebido sería:

db.empleados.find({"apellido" : {"primer_apellido" : "Garcia", "segundo_apellido" : "Lopez"}})

Este tipo de query obliga a que el subdocumento tenga que coincidir totalmente. A veces, puede ser necesario realizar búsquedas solo por alguno de los valores del subdocumento, y es posible mediante la siguiente sentencia:

db.people.find({"apellido.primer_apellido" : "García"})

Sentencia $where

Mediante el uso del método find hemos visto que es posible poder realizar consultas en base a las claves y los valores, pero esto no permite realizar otro tipo de búquedas.

La sentencia $where permite el uso de expresiones en JavaScript para hacer consultas al sistema. Esto admite poder aplicar funciones existentes en JavaScript dando más posibilidades a las consultas y no restringirse únicamente a las funciones proporcionadas por MongoDB.

db.empleados.find( { $where: function() {
   return (hex_md5(this.dni) == "4d2b0d124ca1c391165046a2f745353e")
} } );

El código anterior permite aplicar la función hex_md5 para comparar el dato de un campo.

Otro ejemplo de uso de la función $where es para identificar dos valores de elementos iguales.

db.foo.find({"$where" : function () {
  for (var current in this) {
     for (var other in this) {
          if (current != other && this[current] == this[other]) {
              return true;
          }
      }
   }
      return false;
}});

En el código anterior, haciendo uso de dos sentencias for, es posible recorrer cada documento para poder encontrar valores iguales entre sus conjuntos clave – valor.

Índices

Los índices permiten realizar queries sobre una base de datos de una manera más eficiente. La forma de crear índices en MongoDB es mediante la sentencia:

db.empleados.ensureIndex({"dni" : 1})

En función del tamaño de la base de datos, la creación de un índice puede demorar de segundos a varios minutos. Si la creación del índice se está tomando demasiado tiempo, puede revisarse el estado de esta operación mediante la sentencia db.currentOp().

Los índices almacenan todos sus valores de una forma ordenada para así poder eficientar, también, las operaciones de ordenado sobre los documentos indexados.

Índices compuestos

MongoDB permite además la creación de índices compuestos. Es posible asignar varios valores en un índice con distintos órdenes para mejorar, así, las operaciones de búsqueda y ordenación cuando se accede sobre ellos.

db.empleados.ensureIndex({"edad" : 1, "nombre" : 1})

En esta entrada hemos podido ver cómo MongoDB permite el uso de varios tipos de búsquedas sobre distintos tipos de datos. Además, ofrece muchas posibilidades mediante las consultas tipo $where, donde es posible hacer uso de funciones JavaScript, lo cual, otorga a MongoDB todas las ventajas de este lenguaje. Por último, MongoDB ofrece un sistema de indexación que permite hacer más eficientes las busquedas y las ordenaciones sobre colecciones indexadas.

En conclusión, MongoDB nos permite la realización de consultas muy complejas y de manera muy eficiente. Para más información sobre consultas a tipos de datos complejos con MongoDB, consultar la documentación oficial de MongoDB en este enlace.