En el mundo de las bases de datos, la eficiencia de búsqueda es un factor crítico para garantizar un rendimiento óptimo en aplicaciones que procesan una gran cantidad de datos. MongoDB, una de las bases de datos NoSQL más populares, ofrece una herramienta poderosa llamada Atlas Search diseñada para mejorar las habilidades de búsqueda de texto y otras consultas. En esta publicación, verificaremos lo que los índices de búsqueda, sus beneficios, los índices disponibles para crearlos y algunas mejores prácticas para aprovecharlos al máximo.
Atlas Search es una funcionalidad integrada en MongoDB Atlas que permite realizar búsquedas avanzadas y flexibles en tus datos. A diferencia de los índices tradicionales de MongoDB, que están optimizados para consultas estructuradas, Atlas Search está diseñado para manejar búsquedas de texto completo, consultas semánticas, filtros por rangos y mucho más.
La principal diferencia entre los índices convencionales de Mongo y los de atlas search es que la «indexación» convencional se lleva a cabo sobre el valor «completo» del campo, por lo que es importante utilizar los valores completos al realizar las búsquedas de manera rápida.
Sin embargo, si la búsqueda utiliza valores parciales, como expresiones regulares, no se utilizará un índice. En este caso, la búsqueda implica escanear todos los documentos de la colección, lo que hará que el proceso sea más lento.
Con la implementación del índice de búsqueda (Search Index), se renuncia un poco al espacio de datos, pero a cambio se obtiene la capacidad de buscar valores parciales (texto completo) con la rapidez que ofrece la indexación.
Las principales ventajas de Atlas Search son:
- Búsquedas de texto completo: Permite buscar palabras clave, frases o incluso sinónimos dentro de campos de texto.
- Flexibilidad en las consultas: Soporta consultas complejas, como búsquedas difusas (fuzzy search), búsquedas por proximidad y filtros por rangos.
- Escalabilidad: Se beneficia de la arquitectura escalable de MongoDB Atlas, lo que lo hace ideal para aplicaciones con grandes volúmenes de datos.
- Integración nativa: Al estar integrado en MongoDB Atlas, no necesitas herramientas externas como Elasticsearch.
FLUJO DE FUNCIONAMIENTO ATLAS SEARCH
Tan pronto como se crea un índice de búsqueda, un proceso de Apache Lucene se despliega junto a la base de datos en cada nodo del clúster de Atlas. Los campos de los documentos a indexar se sincronizan automáticamente desde la base de datos hacia Lucene. Una vez que se completa la sincronización inicial, Atlas Search abre un flujo de cambios en la base de datos de MongoDB, recibiendo notificaciones de todas las modificaciones relevantes de los datos en tiempo real.
Estos cambios se aplican inmediatamente a Atlas Search, manteniendo los índices actualizados casi en tiempo real gracias a la canalización de transmisión de datos nativa y basada en eventos de MongoDB. Este proceso es completamente automático y transparente, por lo que no es necesario desarrollar ni mantener sincronizaciones de datos personalizadas, ni gestionar hardware adicional o copias secundarias de la información. Al estar la base de datos y los procesos de indexación ubicados en el mismo nodo físico, se eliminan los saltos de red, lo que reduce el retraso en la replicación y permite ofrecer resultados más actualizados a los usuarios. Además, se mejora el rendimiento de las consultas, devolviendo resultados más rápidamente.
Tipos de Índices en Atlas Search
Atlas Search ofrece varios tipos de índices para optimizar diferentes tipos de búsquedas. Los más importantes son:
Índice de Texto:
- Optimizado para búsquedas de texto completo.
- Permite buscar palabras clave, frases y realizar análisis léxico (stemming, tokenización, etc.).
Índice Numérico:
- Diseñado para campos numéricos.
- Facilita búsquedas por rangos, comparaciones y operaciones matemáticas.
Índice Geoespacial:
- Optimizado para consultas geoespaciales.
- Permite buscar documentos basados en su proximidad a un punto geográfico.
Índice de Fecha:
- Diseñado para campos de fecha y hora.
- Facilita búsquedas por rangos de tiempo, como filtrar documentos creados en un período específico.
Indice de Token:
- Diseñado para campos string que quieren ser consultados para efficient filtering or sort operations.
Tambien existen los indices compuestos que combinan múltiples tipos de índices en uno solo.Útil para consultas que involucran varios campos, como búsquedas de texto en combinación con filtros numéricos o de fecha.
Sin Índices:
- Las consultas pueden volverse lentas, especialmente en colecciones grandes.
- MongoDB debe escanear todos los documentos para encontrar coincidencias.
- No se pueden realizar búsquedas de texto completo avanzadas.
Con Índices Tradicionales de MongoDB:
- Mejora el rendimiento de consultas estructuradas (por ejemplo, búsquedas por ID o rangos numéricos).
- Limitado en capacidades de búsqueda de texto completo y consultas semánticas.
- Con Índices de Atlas Search:
- Permite búsquedas avanzadas de texto completo, difusas y por proximidad.
- Optimiza consultas complejas que involucran múltiples campos y tipos de datos.
- Reduce significativamente el tiempo de respuesta en consultas no estructuradas.
PASOS PARA CREAR UN INDICE DE ATLAS SEARCH
Antes de crear un indice de atlas es muy importante planificar el proceso adecuadamente para evitar que una mala planificacion pueda afectar al rendimiento de las busquedas y la propia base de datos.
En primer lugar hay que identificar las necesidades de la busqueda, el tipo de consultas y por lo tanto los campos involucrados, por ejemplo un campo “title” para busquedas con texto, un campo “price” para filtros numericos por rango o por ordenacion y un campo geoespacial para hacer busquedas cercanas.
Analizar los datos y sus volumenes, con esto se asegura no crear campos indexados con los que posteriormente no se van a realizar consultas y que en posibles crecimientos futuros de los volumenes de datos el indice no consuma demasiados recursos.
Elegir Analizadores de texto adecuados. Para las busquedas por texto existen los analyzers that are policies that combine a tokenizer, which extracts tokens from text, with filters that you define. Atlas Search applies your filters to the tokens to create indexable terms that correct for differences in punctuation, capitalization, filler words, and more.
Un par de ejemplos para ver las posibilidades son lucene.standard convierte los campos de la base de datos en la busqueda para que no sean sensibles a caracteres especiales, mayusculas, etc. o lucene.keyword que trata al texto completo como toda una unidad.
Impacto en el rendimiento. La creación de un índice puede llevar bastante tiempo sobre todo en colecciones con volúmenes muy grandes, por lo tanto también hay que tener en cuenta para hacer las modificaciones o creaciones cuando menos actividad tenga y asegurarse de que el cluster tenga suficientes recursos (CPU, memoria, almacenamiento) para soportar el mismo.
Atlas Search M0 (Free Cluster), M2, and M5 Limitations
- 3 indexes on M0 clusters.
- 5 indexes on M2 clusters.
- 10 indexes on M5 clusters.
- 10 indexes on Flex clusters.
Estas son las limitaciones de indices dependiendo del tipo base de datos configurado en Mongo, por eso es importante la planificación sobre un indice relacionado a sus datos.
EJEMPLO
db.collection(“properties”).createSearchIndex({
name: “properties-search-index”,
definition:
{
"mappings":{
"dynamic":false,
"fields":{
"_id":{
"type":"objectId"
},
"address":{
"type":"document",
"fields":{
"city":{
"type":"string"
},
"map":{
"type":"geo"
},
"completeAddress":{
"type":"string"
}
}
},
"features":{
"type":"document",
"fields":{
"superficie":[
{
"type":"number"
},
{
"type":"token"
}
]
}
},
"status":{
"type":"token"
},
"transaction":{
"type":"document",
"fields":{
"price":[
{
"type":"number"
},
{
"type":"token"
}
]
}
},
"type":{
"type":"token"
}
}
},
"storedSource":{
"include":[
"address.map"
]
}
}
);
Este es un ejemplo de la creación de un índice para una colección con información llamada “properties” que contiene datos de propiedades en venta en una página web. Algunas de las decisiones tomadas “dynamics: false” con esto se especifica que la creación de los índices no sea dinámica, es decir que Atlas Search indexa únicamente los campos que se especifican, aplicando opciones concretas. Si un campo indexado contiene datos polimórficos, solo se indexan los documentos que coinciden con los mapeos definidos en la configuración del índice para ese campo. Los documentos que contienen valores con un tipo de dato diferente al especificado en la definición del índice son ignorados automáticamente.
Otro elemento importante es el atributo storedSource en el cual se especifica que campos se quieren devolver si a la hora de hacer la búsqueda se pasa el parámetro como true, es una especie de “project” propio de Mongo.
Para entender mejor el por qué de los elementos creados en el indice y sus correspondientes tipos vamos a ver un ejemplo de consulta por un usuario que quiere buscar unos tipos de elementos de la colección propiedades con unas características específicas.
db.collection(“properties”).aggregate(
[
{
$search: {
index: "properties-data-search-index",
sort: {
"transaction.price": -1
},
compound: {
must: [
{
geoWithin: {
geometry: {
type: "Polygon",
coordinates: [
[
[40.4132523, -3.7229417],
[40.412362, -3.7228168],
[40.4103825, -3.7221687],
[40.4097391, -3.7219319],
[40.4090942, -3.7217886],
[40.4132523, -3.7229417]
]
]
},
path: "address.map"
}
},
{
in: {
path: "type",
value: ["flat", "house"]
}
},
{
in: {
path: "status",
value: ["available"]
}
},
{
text: {
query: "goya",
path: "address.completeAddress",
fuzzy: { maxEdits: 2 }
}
},
{
equals: {
path: "published",
value: true
}
},
{
in: {
path: "transaction.transactionType",
value: ["sale"]
}
},
{
range: {
path: "transaction.price",
gte: 100000,
lte: 300000
}
}
]
},
returnStoredSource: false
}
},
{ $skip: 0 },
{ $limit: 30 }
]).allowDiskUse(true)
- Se indica la colección y el nombre del índice a utilizar en la búsqueda
- Ordenación por el campo “price” se van a devolver los campos ordenados de mayor a menor precio, de ahi su indice de tipo “token” pero tambien el tipo “number” para hacer esa búsqueda de las propiedades entre 100K y 300K
- Búsqueda por la palabra “goya” en el campo address, su tipo “string” en el indice hace la busqueda por la palabra clave y al no proporcionar un “analyzer” en concreto lo hará con el lucene.standard que se utiliza para no tener en cuenta mayúsculas ni caracteres especiales. De la misma manera “fuzzyEdits” permite especificar el número máximo de cambios permitidos en los caracteres de un término de búsqueda. Estos cambios pueden incluir inserciones, eliminaciones, sustituciones o transposiciones de caracteres.
- Búsqueda geoespacial con geoWithIn se dibuja una especie de polígono y con el indice de tipo “geo” devuelve aquellos elementos con el campo map contenidos entre esas coordenadas.
- Al pasar “returnStoredSource” a false la búsqueda devolverá los elementos con todos sus campos en la base de datos si se pasara a true, entraría en juego el campo especificado anteriormente en el índice.
Los índices de Atlas Search son una herramienta poderosa para mejorar el rendimiento y la flexibilidad de las búsquedas en MongoDB. Al permitir consultas avanzadas de texto completo, filtros por rangos y búsquedas geoespaciales, Atlas Search se convierte en una opción ideal para aplicaciones modernas que requieren capacidades de búsqueda robustas.