MQL reference navigation

$search

The $search stage in the aggregation pipeline runs a vector similarity search over a vector index. It carries exactly one search operator — cosmosSearch, or the deprecated knnBeta — and returns the documents whose stored embedding is closest to a query vector.

$search must be the first stage in the pipeline, and the field named by path must be covered by a vector index.

$search in DocumentDB is a vector search stage. It does not accept text-search operators: a spec such as { $search: { text: { ... } } } is rejected with Unrecognized $search option: text. For full-text queries, use the $text query operator against a text index. For new work, prefer $vectorSearch, which is the current stage for vector search and takes a clearer spec; $search remains for compatibility with existing cosmosSearch and knnBeta queries.

Syntax

{
  $search: {
    index: <string>,
    cosmosSearch: {
      path: <string>,
      vector: [<number>, ...],
      k: <positiveInteger>,
      filter: <document>,
      exact: <boolean>,
      oversampling: <number>
    }
  }
}

Parameters

The stage takes exactly one search operator, plus a small number of options alongside it.

ParameterDescription
cosmosSearchThe search operator, holding the query spec described below. Exactly one operator must be present — supplying both cosmosSearch and knnBeta fails with The $search spec can only contain one search operator., and supplying neither fails with Invalid search spec provided, must include one of the supported operators.
knnBetaDeprecated alias kept for backward compatibility. It takes the same spec as cosmosSearch, except that filter and score are rejected outright. Use cosmosSearch instead.
indexOptional. The name of the index to search, as a string.
returnStoredSourceOptional. Accepted for compatibility and ignored.
countOptional. Parsed and validated, but the resulting count metadata is not yet emitted in the results, so the option currently has no observable effect.

Any other key alongside the operator is rejected with Unrecognized $search option: <name>.

Operator spec

FieldDescription
pathRequired. The document field holding the stored embedding. Must be covered by a vector index. Omitting it fails with $path is required field for using a vector index.
vectorRequired. The query embedding, as a non-empty array of numbers. Omitting it fails with $vector is required field for using a vector index.
kRequired. The number of documents to return, as a positive integer.
filterOptional. A query document intersected with the vector search. Requires vector pre-filtering to be enabled on the server; when it is not, the query fails with $filter is not supported for vector search yet. Not supported at all with knnBeta.
exactOptional. Boolean. Runs an exact search instead of an approximate one.
oversamplingOptional. Widens the candidate set considered during an approximate search, improving recall at the cost of latency.
scoreOptional. Not supported with knnBeta, which rejects it with $score is not supported for knnBeta queries.

Examples

The examples on this page use the following documents in a products collection, with a vector index on embedding.

[
  { "_id": 1, "name": "Espresso Machine", "category": "appliance", "embedding": [0.9, 0.1, 0.05] },
  { "_id": 2, "name": "Coffee Grinder", "category": "appliance", "embedding": [0.85, 0.15, 0.1] },
  { "_id": 3, "name": "Merlot Bottle", "category": "wine", "embedding": [0.05, 0.9, 0.2] },
  { "_id": 4, "name": "Chardonnay Bottle", "category": "wine", "embedding": [0.1, 0.85, 0.25] }
]

Example 1: Nearest neighbors for a query vector

Return the three documents closest to a query embedding:

db.products.aggregate([
  {
    $search: {
      cosmosSearch: {
        path: "embedding",
        vector: [0.88, 0.12, 0.07],
        k: 3
      }
    }
  },
  { $project: { name: 1, category: 1 } }
])
[
  { "_id": 1, "name": "Espresso Machine", "category": "appliance" },
  { "_id": 2, "name": "Coffee Grinder", "category": "appliance" },
  { "_id": 4, "name": "Chardonnay Bottle", "category": "wine" }
]

Example 2: Exact search

Set exact to true to compare against every indexed vector rather than an approximate candidate set. This is slower, and useful when you need a reference result to measure recall against:

db.products.aggregate([
  {
    $search: {
      cosmosSearch: {
        path: "embedding",
        vector: [0.88, 0.12, 0.07],
        k: 3,
        exact: true
      }
    }
  },
  { $project: { name: 1 } }
])

Behavior

  • $search must come first. Placing it anywhere else fails with $search must appear as the initial stage in the pipeline sequence. The same applies when the pipeline already carries a limit ahead of it.
  • One operator per spec. The stage rejects a spec carrying more than one search operator, and a spec carrying none.
  • path must be indexed. The field named by path must be covered by a vector index; see $vectorSearch for creating one.

Related content

  • $vectorSearch — the current vector search stage, and the one to prefer for new queries.
  • $project — shape the documents returned by the search.
  • $limit — narrow the result set further; k already bounds it.