Por qué tu búsqueda no devuelve nada — Y cómo la búsqueda vectorial de MongoDB lo soluciona
La búsqueda por palabras clave solo puede encontrar lo que está literalmente allí. Cuando los usuarios buscan 'laptop bag' y tus documentos dicen 'notebook carrying case', las expresiones regulares no ayudarán. La búsqueda vectorial entiende el significado — y MongoDB Atlas la soporta de forma nativa.
El problema de los resultados ocultos
Tu búsqueda funciona. O al menos, eso parece. Los usuarios escriben una consulta, los resultados aparecen, nadie se queja demasiado. Pero hay una clase de fallo que es casi invisible: los resultados que deberían haber aparecido pero no lo hicieron.
Considera un catálogo de productos para una tienda en línea. Un usuario escribe "laptop bag" en la barra de búsqueda. El sistema devuelve dos productos que contienen la frase "laptop bag" en su título o descripción. Parece correcto.
Pero hay una docena de otros productos relevantes en el catálogo. Un "notebook carrying case", una "padded sleeve for 15-inch computers", una "tech commuter backpack with device compartment". Ninguno de ellos contiene la cadena literal "laptop bag". Así que ninguno de ellos aparece.
El usuario ve dos resultados y asume que eso es todo lo que tienes. El sistema ocultó silenciosamente los productos más relevantes porque el mecanismo de búsqueda es estructuralmente incapaz de entender lo que el usuario quería decir.
Cómo funciona realmente la búsqueda por palabras clave
La mayoría de las implementaciones de búsqueda internas que he encontrado utilizan alguna forma de regex o coincidencia de subcadenas (substring matching). La cadena de consulta se escanea contra un conjunto de campos indexados — productName, description, category, specifications — y se devuelve cualquier documento que contenga esa secuencia exacta de caracteres.
db.products.find({
$or: [
{ productName: { $regex: "laptop bag", $options: "i" } },
{ description: { $regex: "laptop bag", $options: "i" } },
{ category: { $regex: "laptop bag", $options: "i" } },
{ specifications: { $regex: "laptop bag", $options: "i" } },
]
})
Esto funciona cuando el lenguaje del usuario coincide exactamente con el lenguaje del documento. Buscar "laptop" encuentra documentos que dicen "laptop". Buscar "bag" también funciona porque es una subcadena de "bags".
Pero el enfoque es puramente léxico. No tiene concepto de significado.
Dónde falla
Los modos de fallo son sistemáticos, no casos excepcionales:
| El usuario busca | Espera encontrar | Por qué falla la búsqueda por palabras clave |
|---|---|---|
| "laptop bag" | Fundas para portátiles, mochilas tecnológicas | El producto dice "estuche de transporte", no "bolso" |
| "winter jacket" | Parkas, abrigos acolchados, chaquetas aislantes | El producto dice "ropa de abrigo térmica" |
| "kids tablet" | Dispositivos educativos, tablets de aprendizaje | El producto dice "pantalla interactiva para niños" |
| "gift for a runner" | Zapatillas de correr, monitores de actividad física, equipo de hidratación | Ningún campo contiene el concepto de "regalo para un corredor" |
| "something for a road trip" | Neveras portátiles, cargadores de coche, almohadas de viaje | Las consultas conceptuales no tienen una coincidencia literal |
Ninguna cantidad de indexación de campos puede anticipar todas las formas en que un usuario podría expresar su intención. La limitación no está en la implementación, sino en el paradigma.
La tirita de la desnormalización
Una reacción común es desnormalizar: extraer datos relacionados de otras colecciones al documento buscable. Por ejemplo, tu catálogo tiene una colección products con metadatos básicos, pero las descripciones ricas en palabras clave viven en una colección productDetails separada, vinculada por SKU.
// Antes: documento de producto ligero con referencias
{
"_id": "prod_2241",
"productName": "TechShield Commuter Pack",
"brand": "TechShield",
"skus": ["TS-441", "TS-442", "TS-443"]
}
// Después: enriquecido con metadatos de detalle
{
"_id": "prod_2241",
"productName": "TechShield Commuter Pack",
"brand": "TechShield",
"skus": ["TS-441", "TS-442", "TS-443"],
"variantNames": [
"TechShield Padded Laptop Bag 15-inch, Black",
"TechShield Padded Laptop Bag 15-inch, Navy",
"TechShield Padded Laptop Sleeve 13-inch, Gray"
]
}
Ahora, una búsqueda de "laptop bag" coincidirá con este producto porque la cadena aparece en variantNames. Esto funciona como una solución táctica. Pero introduce una desventaja: cada documento de producto debe actualizarse cada vez que cambian los datos de las variantes, la redundancia debe mantenerse con el tiempo y sigues intentando ponerte al día con el vocabulario del usuario.
Un usuario que busca "backpack for my MacBook" seguirá sin coincidir con "Padded Laptop Bag" a menos que sigas expandiendo los campos desnormalizados. Estás parcheando un sistema fundamentalmente léxico, sinónimo a sinónimo.
Búsqueda vectorial: coincidencia por significado
La búsqueda vectorial adopta un enfoque completamente diferente. En lugar de comparar secuencias de caracteres, compara el significado.
La idea central: convertir texto en representaciones numéricas de alta dimensión llamadas embeddings. Estos son generados por modelos de machine learning (Voyage AI, text-embedding-3-small de OpenAI, modelos de código abierto como nomic-embed-text) entrenados en enormes corpus de texto. Los modelos aprenden relaciones semánticas entre palabras y conceptos.
En el espacio de embeddings:
- Las palabras con significados similares se agrupan cerca (pequeña distancia vectorial)
- Las palabras con significados diferentes están muy separadas (gran distancia vectorial)
"laptop bag" → [0.021, -0.187, 0.443, 0.078, ..., 0.312] (768 dimensions)
"notebook sleeve" → [0.019, -0.174, 0.451, 0.065, ..., 0.298] (nearby)
"refrigerator" → [-0.342, 0.501, -0.113, 0.227, ..., -0.089] (distant)
Cuando un usuario busca "laptop bag", la consulta se convierte en un embedding y se compara con los embeddings precalculados de todos los documentos. Los resultados se clasifican por similitud de coseno. El "notebook carrying case" aparece — no por una coincidencia de cadena, sino porque el modelo entiende que los estuches de transporte y los bolsos para portátiles habitan en el mismo vecindario semántico.
MongoDB Atlas Vector Search: implementación
MongoDB Atlas soporta la búsqueda vectorial de forma nativa. No hay una infraestructura de búsqueda separada, ni un sidecar de Elasticsearch, ni una pipeline de sincronización de datos. Se ejecuta en tu clúster existente.
Paso 1: Generar embeddings
Para cada documento, concatena los campos semánticamente significativos y pásalos a través de un modelo de embedding:
def build_embedding_text(product):
parts = [
product.get("productName", ""),
product.get("brand", ""),
product.get("description", ""),
product.get("category", ""),
product.get("specifications", ""),
]
return " | ".join(part for part in parts if part)
Para la mochila de viaje, esto produce:
"TechShield Commuter Pack | TechShield | Durable backpack with padded
device compartment and organizer pockets | Bags & Accessories | Water-
resistant nylon, fits up to 15-inch devices"
El embedding resultante captura el concepto — "un bolso para llevar dispositivos tecnológicos, formato mochila, acolchado protector". Almacénalo como un nuevo campo en el documento:
{
"_id": "prod_2241",
"productName": "TechShield Commuter Pack",
"embedding": [0.019, -0.174, 0.451, 0.065, "...", 0.298]
}
Paso 2: Crear un índice de búsqueda vectorial
Define el índice en MongoDB Atlas:
{
"type": "vectorSearch",
"fields": [
{
"path": "embedding",
"type": "vector",
"numDimensions": 768,
"similarity": "cosine"
}
]
}
El numDimensions debe coincidir con el tamaño de salida de tu modelo de embedding. La similitud de coseno es la elección estándar para los embeddings de texto.
Paso 3: Consultar con $vectorSearch
En el momento de la búsqueda, incrusta la consulta del usuario con el mismo modelo y pásala a la etapa de agregación $vectorSearch:
db.products.aggregate([
{
$vectorSearch: {
index: "product_vector_index",
path: "embedding",
queryVector: embedQuery("laptop bag"),
numCandidates: 100,
limit: 20
}
},
{
$project: {
productName: 1,
brand: 1,
category: 1,
score: { $meta: "vectorSearchScore" }
}
}
])
Una búsqueda de "laptop bag" ahora devuelve:
| Clasificación | Producto | Puntuación |
|---|---|---|
| 1 | TechShield Commuter Pack | 0.92 |
| 2 | SlimGuard Notebook Sleeve 15" | 0.89 |
| 3 | UrbanGear Padded Carrying Case | 0.86 |
| 4 | ProTravel Tech Backpack | 0.81 |
El producto TechShield aparece — no por una coincidencia de cadena, sino porque el modelo entiende que una "mochila de viaje con compartimento acolchado para dispositivos" es semánticamente lo que alguien quiere decir cuando busca "laptop bag".
Por qué esto es fundamentalmente mejor
| Dimensión | Búsqueda por palabras clave / Regex | Búsqueda vectorial |
|---|---|---|
| Mecanismo de coincidencia | Coincidencia exacta de subcadena | Similitud semántica |
| Maneja sinónimos | No ("bag" ≠ "case" ≠ "sleeve") | Sí (entiende la equivalencia) |
| Maneja la parafraseo | No | Sí ("algo para llevar mi portátil" → bolsos) |
| Requiere desnormalización | Sí — debe copiar datos en campos buscables | No — el significado se captura en el embedding |
| Carga de mantenimiento | Alta — mantener campos redundantes sincronizados | Baja — re-embed solo cuando el texto fuente cambia |
| Tolerancia a errores tipográficos | No ("laptpo bag" falla) | Parcial (los embeddings son robustos a variaciones menores) |
| Consultas conceptuales | Imposible | Sí ("equipo para viajeros tecnológicos" muestra productos relevantes) |
| Calidad de clasificación | Binaria (coincidencia o no coincidencia) | Puntuación de relevancia continua |
La ventaja más significativa es la última. La búsqueda por palabras clave es binaria: un documento contiene la cadena o no. La búsqueda vectorial produce una puntuación de relevancia, lo que significa que los resultados pueden clasificarse por cuán estrechamente coinciden con la intención del usuario.
Búsqueda híbrida: la elección pragmática
La búsqueda vectorial pura tiene una debilidad: las coincidencias exactas. Si un usuario escribe el nombre preciso del producto — "TechShield Commuter Pack 15-inch Black" — la búsqueda por palabras clave lo encontrará inmediatamente, mientras que la búsqueda vectorial podría clasificarlo alto, pero no necesariamente primero.
MongoDB Atlas soporta la búsqueda híbrida — combinando puntuaciones de búsqueda de texto completo con puntuaciones de similitud vectorial utilizando Reciprocal Rank Fusion (RRF):
db.products.aggregate([
{
$vectorSearch: {
index: "product_vector_index",
path: "embedding",
queryVector: embedQuery("laptop bag"),
numCandidates: 100,
limit: 50
}
},
{
$unionWith: {
coll: "products",
pipeline: [
{
$search: {
index: "product_text_index",
text: {
query: "laptop bag",
path: ["productName", "brand", "description", "category"]
}
}
},
{ $limit: 50 }
]
}
}
// Reciprocal Rank Fusion to merge and re-rank results
])
Esto te ofrece lo mejor de ambos mundos:
- Las búsquedas exactas de nombres de productos se manejan de forma nítida mediante la coincidencia de palabras clave.
- Las consultas exploratorias o conceptuales ("algo impermeable para hacer senderismo con mi portátil") se manejan mediante la similitud vectorial.
- Ambas señales se fusionan en un único conjunto de resultados clasificados.
Enriquecimiento de embeddings para mejores resultados
Si bien la búsqueda vectorial resuelve el problema de los resultados ocultos sin desnormalización, puedes mejorar aún más la calidad incluyendo datos relacionados en el texto fuente del embedding. Esto es un primo más ligero del enfoque de desnormalización — en lugar de reestructurar documentos para el escaneo de palabras clave, añades contexto al texto que se incrusta:
def build_enriched_embedding_text(product, variant_names):
base = build_embedding_text(product)
variants = " | ".join(variant_names)
return f"{base} | Variants: {variants}"
Esto proporciona al modelo de embedding un contexto más rico, fortaleciendo la señal semántica para los términos que aparecen en los detalles de las variantes pero no en la lista principal del producto. La estructura del documento permanece inalterada — solo el embedding se beneficia.
Cuándo adoptar esto
Si tu búsqueda está respaldada por regex o consultas $text básicas en MongoDB, el camino a seguir está claro:
-
Inmediato: Audita tus consultas de búsqueda de mayor tráfico. Identifica cuáles devuelven menos resultados de los que deberían. Esto cuantifica el problema de los resultados ocultos en tu sistema.
-
A corto plazo: Si la adopción de la búsqueda vectorial necesita tiempo, considera la desnormalización dirigida para las consultas con peor rendimiento. Esto te da tiempo sin cambios arquitectónicos.
-
A medio plazo: Implementa MongoDB Atlas Vector Search. Genera embeddings a partir de los metadatos de tus documentos, crea el índice y valida con pruebas A/B contra la búsqueda actual.
-
A largo plazo: Adopta la búsqueda híbrida combinando señales de palabras clave y vectoriales. Extiende a superficies adicionales — descubrimiento de productos, recomendaciones, búsqueda conversacional.
El resultado es una experiencia de búsqueda donde los usuarios encuentran lo que buscan, incluso cuando no utilizan las palabras exactas que aparecen en tus datos. Eso no es un lujo. Para cualquier sistema donde la búsqueda impulse el engagement o los ingresos, es la diferencia entre un producto que se siente inteligente y uno que se siente roto.
Este artículo forma parte de una serie sobre bases de datos e infraestructura de datos.
Artículos Relacionados

Construyendo un Pipeline de Embeddings en Producción con MongoDB Atlas y Voyage AI
Generar embeddings es la parte fácil. Mantenerlos sincronizados a medida que tus datos cambian — a escala, sin tiempo de inactividad — es donde reside la verdadera ingeniería. Aquí te explicamos cómo construir el pipeline completo en MongoDB Atlas.

Patrones de Bases de Datos que Debes Conocer Antes de Elegir tu Próxima Base de Datos
La elección entre Postgres y MongoDB no se trata de cuál es 'mejor'. Se trata de comprender los patrones de acceso, los requisitos de consistencia y las restricciones operativas de tu sistema.

Construyendo para la Escala: Patrones de Arquitectura que Realmente Funcionan
La mayoría de los consejos sobre escalabilidad son genéricos. Aquí presentamos los patrones que han funcionado consistentemente en sistemas reales que manejan millones de solicitudes, y aquellos que suenan bien pero fallan en la práctica.