Vector search

$vectorSearch with vector indexes on the same nodes as your documents.

$vectorSearch finds the documents whose vectors are closest to your query's. You store the vector as another field of the document and create a search index of type vectorSearch.

Requirements

  • The vectors of your documents, computed with an embedding model.
  • A user that can create search indexes on the collection.

Create the index

JavaScript
db.products.createSearchIndex({
  name: "vector",
  type: "vectorSearch",
  definition: {
    fields: [
      { type: "vector", path: "embedding", numDimensions: 768, similarity: "cosine" },
      { type: "filter", path: "category" },
    ],
  },
});
JavaScript
db.products.aggregate([
  {
    $vectorSearch: {
      index: "vector",
      path: "embedding",
      queryVector: queryEmbedding,
      numCandidates: 200,
      limit: 10,
      filter: { category: "books" },
    },
  },
  { $project: { name: 1, score: { $meta: "vectorSearchScore" } } },
]);

Exact or approximate

By default the search is approximate: it walks an HNSW graph per range. With exact: true it compares against every vector and the result is the same on any replica. Without exact, two replicas can return different documents at the same timestamp, because each links its graph as it applies the changes.

Check

The pipeline of the example returns up to 10 documents of the requested category, with the vectorSearchScore of each document.

Common problems

  • The index does not fit your vectors because numDimensions is not the size your model gives. Create it with that size.
  • Two replicas return different documents for the same query. That is expected without exact; with exact: true the result is the same on all of them.

See also