---
type: api
title: Evaluate kNN search settings
description: **All methods and paths for this operation:**
url: https://www.elastic.co/elastic/docs-builder/docs/4641/api/doc/elasticsearch/operation/operation-knn-eval
resource: https://www.elastic.co/elastic/docs-builder/docs/4641/api/doc/elasticsearch/operation/operation-knn-eval
products:
  - Elasticsearch
---

# Evaluate kNN search settings

Authentication: required

Availability: Planned

## Paths

- `POST` (also `GET`) `/{index}/_knn_eval`

#### Path parameters

- `index` (union string | string[]) — required
  A comma-separated list of index names to search.

## Description

Estimate the recall and cost of approximate kNN search configurations on a `dense_vector` field against a more thorough baseline.
The field must use the `bbq_disk` index type, and must not be inside a nested object.

Each `knn_settings` entry reports the mean recall of the baseline's top `k`, not of relevance judgments, plus included and excluded query counts and cost totals.
A query is excluded from the mean recall when the candidate finds a document scoring above the baseline's lowest top `k` score.
A baseline returning fewer than `k` hits fails that query, because recall at `k` is undefined.
All configurations run against one point in time.

The default baseline uses a `visit_percentage` of 20 and a `rescore_vector.oversample` of 100.
An exact full-precision baseline must be requested explicitly with `allow_exact_baseline`, and is limited to 100 million vector-by-query comparisons.

The request is refused when the `search.knn_eval.enabled` cluster setting or the `index.knn_eval.enabled` index setting is `false`.

## Required authorization

- Index privileges: `read`, `view_index_metadata`

## Query string parameters

- `ignore_unavailable` (boolean · default: false) — optional
  If `false`, the request returns an error if it targets a missing or closed index.
- `allow_no_indices` (boolean · default: true) — optional
  If `false`, the request returns an error if any wildcard expression, index alias, or `_all` value targets only missing or closed indices.
This behavior applies even if the request targets other open indices.
- `expand_wildcards` (union oneOf · default: open) — optional
  The type of index that wildcard patterns can match.
It supports comma-separated values, such as `open,hidden`.

Supported values include:
  - `all`: Match any data stream or index, including hidden ones.
  - `open`: Match open, non-hidden indices. Also matches any non-hidden data stream.
  - `closed`: Match closed, non-hidden indices. Also matches any non-hidden data stream. Data streams cannot be closed.
  - `hidden`: Match hidden data streams and hidden indices. Must be combined with `open`, `closed`, or `both`.
  - `none`: Wildcard expressions are not accepted.
  Values: `all`, `open`, `closed`, `hidden`, `none`
- `wait_for_completion` (boolean · default: true) — optional
  If `true`, the request waits for the evaluation to complete.
A large evaluation can run for minutes, and closing the connection, for example because of a client or proxy timeout, cancels it.
If `false`, the request returns a task identifier, and stores the completed response for retrieval through the task management API.

## Request body

`application/json`

- `field` (string) — required
  The `dense_vector` field to evaluate.
- `k` (number) — required
  The number of nearest neighbors to compute the recall for, from 1 to 1000.
- `query_source` (union oneOf) — required
  The source of the query vectors.
  - **from: docs** (`from: docs`)
    Samples the query vectors from the stored documents.
    - `from` (enum) — required
      Values: `docs`
    - `size` (number) — required
      The number of documents to sample, from 1 to 1000.
    - `seed` (number) — optional
      The seed of the sampling, to sample the same documents across requests.
  - **from: vectors** (`from: vectors`)
    Uses the query vectors in the request.
    - `from` (enum) — required
      Values: `vectors`
    - `vectors` (object[]) — required
      The query vectors, from 1 to 1000 entries with unique identifiers.
      - `id` (string) — required
        The identifier of the query, which identifies it in the `failures` of the response.
      - `query_vector` (union oneOf) — required
        The query vector.
        One of: `number[]` or `string`
- `baseline` (object) — optional
  The settings of the search that the `knn_settings` entries are compared with.
If not specified, it uses a `visit_percentage` of 20 and a `rescore_vector.oversample` of 100.
  - `visit_percentage` (number) — optional
    The percentage of postings to visit, from 0 to 100.
`0` selects the automatic visit calculation.
  - `num_candidates` (number) — optional
    The number of nearest neighbor candidates to consider per shard.
It can't be less than `k`, or more than 10000 (9999 with sampling).
  - `rescore_vector` (object) — optional
    The rescoring of the candidates. Only applies to quantized fields.
    - `oversample` (number) — required
      Applies the specified oversample factor to k on the approximate kNN search
  - `exact` (boolean · default: false) — optional
    If `true`, compares every vector at full precision.
Only applies to the `baseline`, requires `allow_exact_baseline`, and can't be combined with other settings.
- `knn_settings` (object[]) — required
  The kNN search settings to evaluate, from 1 to 32 unique entries.
  - `visit_percentage` (number) — optional
    The percentage of postings to visit, from 0 to 100.
`0` selects the automatic visit calculation.
  - `num_candidates` (number) — optional
    The number of nearest neighbor candidates to consider per shard.
It can't be less than `k`, or more than 10000 (9999 with sampling).
  - `rescore_vector` (object) — optional
    The rescoring of the candidates. Only applies to quantized fields.
    - `oversample` (number) — required
      Applies the specified oversample factor to k on the approximate kNN search
  - `exact` (boolean · default: false) — optional
    If `true`, compares every vector at full precision.
Only applies to the `baseline`, requires `allow_exact_baseline`, and can't be combined with other settings.
- `allow_exact_baseline` (boolean · default: false) — optional
  If `true`, the `baseline` can be `exact`.
An exact baseline compares every vector at full precision, and can severely slow down other searches.

## Response

`application/json`

- `query_source` (object)
  The source of the query vectors.
Not returned when `wait_for_completion` is `false`.
  - `from` (enum)
    How the query vectors were chosen.
    Values: `docs`, `vectors`
- `baseline` (object)
  The settings of the baseline search.
Not returned when `wait_for_completion` is `false`.
  - `visit_percentage` (number)
    The percentage of postings to visit, from 0 to 100.
`0` selects the automatic visit calculation.
  - `num_candidates` (number)
    The number of nearest neighbor candidates to consider per shard.
It can't be less than `k`, or more than 10000 (9999 with sampling).
  - `rescore_vector` (object)
    The rescoring of the candidates. Only applies to quantized fields.
    - `oversample` (number)
      Applies the specified oversample factor to k on the approximate kNN search
  - `exact` (boolean · default: false)
    If `true`, compares every vector at full precision.
Only applies to the `baseline`, requires `allow_exact_baseline`, and can't be combined with other settings.
  - `rescore_window_capped` (boolean · default: false)
    If `true`, the number of vectors to rescore exceeded the limit of 10000.
  - `quantized_scores` (boolean · default: false)
    If `true`, the hits were not rescored, so their scores are estimates, and no query is excluded from the mean recall.
- `baseline_took_ms` (number)
  The time the baseline searches took, in milliseconds.
Not returned when `wait_for_completion` is `false`.
- `baseline_vector_ops` (number)
  The number of vector operations of the baseline searches.
Not returned when `wait_for_completion` is `false`.
- `baseline_vector_ops_kind` (enum)
  What `baseline_vector_ops` counts.
Not returned when `wait_for_completion` is `false`.

Supported values include:
  - `full_precision_scan`: Full-precision comparisons across all the matching vectors.
  - `quantized_visit_plus_rescore`: Quantized visits plus full-precision rescoring.
  Values: `full_precision_scan`, `quantized_visit_plus_rescore`
- `results` (object[])
  The results of each `knn_settings` entry, in the order of the request.
Not returned when `wait_for_completion` is `false`.
  - `knn_settings` (object)
    The evaluated settings.
    - `visit_percentage` (number)
      The percentage of postings to visit, from 0 to 100.
`0` selects the automatic visit calculation.
    - `num_candidates` (number)
      The number of nearest neighbor candidates to consider per shard.
It can't be less than `k`, or more than 10000 (9999 with sampling).
    - `rescore_vector` (object)
      The rescoring of the candidates. Only applies to quantized fields.
      - `oversample` (number)
        Applies the specified oversample factor to k on the approximate kNN search
    - `exact` (boolean · default: false)
      If `true`, compares every vector at full precision.
Only applies to the `baseline`, requires `allow_exact_baseline`, and can't be combined with other settings.
    - `rescore_window_capped` (boolean · default: false)
      If `true`, the number of vectors to rescore exceeded the limit of 10000.
    - `quantized_scores` (boolean · default: false)
      If `true`, the hits were not rescored, so their scores are estimates, and no query is excluded from the mean recall.
  - `recall` (union number | string) — nullable
    The mean recall of the included queries, or `null` if no query is included.
  - `included_queries` (number)
    The number of queries included in the mean recall.
  - `excluded_queries` (number)
    The number of queries excluded from the mean recall, because the search found a document scoring above the baseline's lowest top `k` score.
  - `took_ms` (number)
    The time the searches took, in milliseconds.
  - `vector_ops` (number)
    The number of vector operations of the searches.
- `failures` (map string to object)
  The queries that failed, by query identifier.
Not returned when `wait_for_completion` is `false`.
  Map values (object)
  - `error` (object)
    - `type` (string)
      The type of error
    - `reason` (union string) — nullable
      A human-readable explanation of the error, in English.
      One of: `string`
    - `stack_trace` (string)
      The server stack trace. Present only if the `error_trace=true` parameter was sent with the request.
    - `caused_by` (object) — recursive
      Same fields as `error` in `failures`
    - `root_cause` (object[]) — recursive
      Same fields as `error` in `failures`
    - `suppressed` (object[]) — recursive
      Same fields as `error` in `failures`
- `task` (string)
  The identifier of the task that runs the evaluation.
Only returned when `wait_for_completion` is `false`.
## Code examples

#### Console

```console
POST my-index/_knn_eval
{
  "field": "my_vector",
  "k": 10,
  "query_source": {
    "from": "docs",
    "size": 100,
    "seed": 42
  },
  "knn_settings": [
    { "visit_percentage": 1 },
    { "visit_percentage": 5 }
  ]
}
```

#### JavaScript

```javascript
const response = await client.knnEval({
  index: "my-index",
  field: "my_vector",
  k: 10,
  query_source: {
    from: "docs",
    size: 100,
    seed: 42,
  },
  knn_settings: [
    {
      visit_percentage: 1,
    },
    {
      visit_percentage: 5,
    },
  ],
});
```

#### Python

```python
resp = client.knn_eval(
    index="my-index",
    field="my_vector",
    k=10,
    query_source={
        "from": "docs",
        "size": 100,
        "seed": 42
    },
    knn_settings=[
        {
            "visit_percentage": 1
        },
        {
            "visit_percentage": 5
        }
    ],
)
```

#### curl

```curl
curl -X POST "$ELASTICSEARCH_URL/my-index/_knn_eval" \
  -H "Authorization: ApiKey $ELASTIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "field": "my_vector",
    "k": 10,
    "query_source": {
      "from": "docs",
      "size": 100,
      "seed": 42
    },
    "knn_settings": [
      {
        "visit_percentage": 1
      },
      {
        "visit_percentage": 5
      }
    ]
  }'
```

#### PHP

```php
$resp = $client->knnEval([
    "index" => "my-index",
    "body" => [
        "field" => "my_vector",
        "k" => 10,
        "query_source" => [
            "from" => "docs",
            "size" => 100,
            "seed" => 42,
        ],
        "knn_settings" => array(
            [
                "visit_percentage" => 1,
            ],
            [
                "visit_percentage" => 5,
            ],
        ),
    ],
]);
```

#### Ruby

```ruby
response = client.knn_eval(
  index: "my-index",
  body: {
    "field": "my_vector",
    "k": 10,
    "query_source": {
      "from": "docs",
      "size": 100,
      "seed": 42
    },
    "knn_settings": [
      {
        "visit_percentage": 1
      },
      {
        "visit_percentage": 5
      }
    ]
  }
)
```

## Response examples

#### Evaluate kNN search settings

`application/json`

A response from `POST my-index/_knn_eval`, with the recall of each `knn_settings` entry against the default baseline.

```json
{
  "query_source": {
    "from": "docs"
  },
  "baseline": {
    "visit_percentage": 20.0,
    "rescore_vector": {
      "oversample": 100.0
    }
  },
  "baseline_took_ms": 412,
  "baseline_vector_ops": 2048000,
  "baseline_vector_ops_kind": "quantized_visit_plus_rescore",
  "results": [
    {
      "knn_settings": {
        "visit_percentage": 1.0
      },
      "recall": 0.87,
      "included_queries": 100,
      "excluded_queries": 0,
      "took_ms": 35,
      "vector_ops": 102400
    },
    {
      "knn_settings": {
        "visit_percentage": 5.0
      },
      "recall": 0.97,
      "included_queries": 99,
      "excluded_queries": 1,
      "took_ms": 96,
      "vector_ops": 512000
    }
  ],
  "failures": {}
}
```

