Búsqueda semántica con $vectorSearch
Guarda embeddings junto a tus documentos y busca por significado con un índice vectorial.
Con $vectorSearch buscas documentos por lo que significan y no por las palabras exactas. Los vectores se guardan como
un campo más del documento y el índice vive en los mismos nodos que los datos: no hace falta otra base de datos.
Esta guía usa Python, PyMongo y el modelo all-MiniLM-L6-v2 de sentence-transformers, que da vectores de 384
dimensiones. Cualquier modelo de embeddings sirve; ajusta numDimensions a su tamaño.
Shell
pip install pymongo sentence-transformers1. Guarda los documentos con su vector
Python
from pymongo import MongoClient
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("all-MiniLM-L6-v2") # 384 dimensions
client = MongoClient("mongodb://app:<password>@node-01:27017/?tls=true&tlsCAFile=./ca.pem")
articles = client.kb.articles
docs = [
{"title": "Add a node", "body": "Create an enrollment token and start the binary with --join."},
{"title": "Drain a node", "body": "teseladb admin node drain moves its replicas before you shut it down."},
]
for doc in docs:
doc["embedding"] = model.encode(doc["title"] + ". " + doc["body"]).tolist()
articles.insert_many(docs)2. Crea el índice vectorial
Python
from pymongo.operations import SearchIndexModel
articles.create_search_index(SearchIndexModel(
name="vector",
type="vectorSearch",
definition={"fields": [
{"type": "vector", "path": "embedding", "numDimensions": 384, "similarity": "cosine"}
]},
))3. Busca por significado
Python
query = model.encode("how do I take a machine out of the cluster?").tolist()
results = articles.aggregate([
{"$vectorSearch": {"index": "vector", "path": "embedding", "queryVector": query,
"numCandidates": 100, "limit": 3}},
{"$project": {"title": 1, "score": {"$meta": "vectorSearchScore"}}},
])
for r in results:
print(round(r["score"], 3), r["title"])La pregunta no contiene la palabra «drain», pero el resultado más cercano es el artículo que la explica.
4. Filtra y afina
- Añade un campo
filteral índice ({"type": "filter", "path": "categoria"}) y pasafilteren$vectorSearchpara buscar solo en una categoría. - Sube
numCandidatespara mejorar la exactitud a cambio de tiempo, o usaexact: truepara comparar con todos los vectores. Conexact, el resultado es el mismo en cualquier réplica. - Un documento insertado aparece en la búsqueda en cuanto se confirma la escritura.
Última actualización