> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cyborg.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Query

Finds the nearest neighbors of one or more query vectors. With `QueryContents`, the service embeds the text first (the index needs an `EmbeddingModel`). With `Text`, the query becomes **hybrid**: BM25 full-text ranking is fused with the vector ranking.

```go theme={null}
func (e *EncryptedIndex) Query(ctx context.Context, input QueryInput) (*QueryResponse, error)
```

`input` is either `QueryParams` (sent as JSON) or `BinaryQueryParams` (vectors sent as binary, faster for large batches).

### Parameters

#### QueryParams

Optional scalar fields are pointers: leave them `nil` to use the service default.

| Field | Type | Default | Description |
| - | - | - | - |
| `QueryVector` | `[]float32` | `nil` | One query vector. |
| `BatchQueryVectors` | `[][]float32` | `nil` | A batch of query vectors. Takes precedence over `QueryVector`. |
| `QueryContents` | `*string` | `nil` | Text for the service to embed and search with. Requires an index created with `EmbeddingModel`. |
| `TopK` | `int32` | `0` (service default: `100`) | Results to return per query. `0` means the service default. |
| `NProbes` | `*int32` | `nil` (service default: auto) | Clusters to probe. Higher values improve recall and add latency. |
| `Filters` | `map[string]interface{}` | `nil` | Metadata filter. See [Metadata filtering](../types#metadata-filtering). |
| `Include` | `[]string` | `nil` (service default: `[]`) | Extra fields per result: `"distance"` and `"metadata"`. `Id` is always returned. See [Result fields](#result-fields). |
| `Greedy` | `*bool` | `nil` (service default: `false`) | Use greedy search. |
| `RerankMult` | `*int32` | `nil` (service default: `50`) | Stage 1 returns `TopK * RerankMult` candidates before reranking narrows them to `TopK`. |
| `Text` | `*string` | `nil` | Query text for a BM25 leg, which makes the query hybrid. Requires an index with at least one full-text field. A query vector is still required. |
| `TextFields` | `[]string` | `nil` (all full-text fields) | Full-text fields the BM25 leg searches. |
| `TextFieldWeights` | `[]float32` | `nil` (`1.0` each) | Weight per searched field, in the same order as `TextFields`. |
| `RequireAllTerms` | `*bool` | `nil` (service default: `false`) | Match only items containing every query term (AND) instead of any term (OR). |
| `Alpha` | `*float64` | `nil` (service default: `0.5`) | Blend of the two legs, in `[0, 1]`: `0` is pure BM25, `1` is pure vector. |
| `RrfK` | `*float64` | `nil` (service default: `60`) | Reciprocal rank fusion smoothing constant. Must be `> 0`. |
| `WindowMult` | `*int32` | `nil` (service default: `3`) | Candidates retrieved per leg, as a multiple of `TopK`. Must be `>= 1`. |

#### BinaryQueryParams

The same fields as `QueryParams`, except:

* `QueryVectors [][]float32` replaces `QueryVector` and `BatchQueryVectors`.
* There is no `QueryContents`.

### Returns

`*QueryResponse`, whose `Results` holds exactly one of:

* `Results.ArrayOfQueryResultItem` (`*[]QueryResultItem`): one query vector.
* `Results.ArrayOfArrayOfQueryResultItem` (`*[][]QueryResultItem`): two or more query vectors.

A query with exactly one vector always returns single results, even when it's sent as a batch or through the binary path.

#### Result fields

| Field / method | Description |
| - | - |
| `Id string` | Always set. |
| `GetDistance()`, `HasDistance()` | Vector queries, when `"distance"` is in `Include`. Lower is closer. |
| `GetScore()`, `HasScore()` | Hybrid queries only, instead of distance. Higher is more relevant. |
| `Metadata map[string]interface{}` | When `"metadata"` is in `Include`. |

`Query` never returns vectors or contents, even when they're listed in `Include`. To read them, pass the result IDs to [`Get`](./get).

### Errors

<AccordionGroup>
  <Accordion title="*ValidationError">
    * Wraps `ErrEmptyQueryVectors`, `ErrInconsistentDimension`, or `ErrUnsupportedQueryType`. A `BinaryQueryParams` has no vectors or vectors of different lengths, or `input` is another type. Returned before any request is sent.
    * The service rejects the query (HTTP `400`/`422`): no query input, wrong vector dimension, `Text` on an index without full-text fields, or an out-of-range `Alpha`, `RrfK`, or `WindowMult`. Other numeric parameters aren't range-checked.
  </Accordion>

  <Accordion title="*AuthenticationError">
    The `apiKey` is invalid (HTTP `401`).
  </Accordion>

  <Accordion title="*ServiceError / *TransportError">
    The service returns `5xx` or can't be reached.
  </Accordion>
</AccordionGroup>

See [Errors](../errors).

### Example Usage

#### Single vector

```go theme={null}
resp, err := index.Query(ctx, cyborgdb.QueryParams{
    QueryVector: []float32{0.1, 0.2, 0.3, 0.4},
    TopK:        2,
    Include:     []string{"distance", "metadata"},
})
if err != nil {
    log.Fatal(err)
}

for _, r := range *resp.Results.ArrayOfQueryResultItem {
    fmt.Printf("%s %.4f %v\n", r.Id, r.GetDistance(), r.Metadata)
}
// Output:
// doc1 0.0000 map[category:news]
// doc2 0.8000 map[category:research]
```

#### Batch of vectors

```go theme={null}
resp, err := index.Query(ctx, cyborgdb.QueryParams{
    BatchQueryVectors: [][]float32{
        {0.1, 0.2, 0.3, 0.4},
        {0.5, 0.6, 0.7, 0.8},
    },
    TopK: 1,
})
if err != nil {
    log.Fatal(err)
}

for i, results := range *resp.Results.ArrayOfArrayOfQueryResultItem {
    fmt.Println(i, results[0].Id)
}
// Output:
// 0 doc1
// 1 doc2
```

#### BinaryQueryParams

```go theme={null}
resp, err := index.Query(ctx, cyborgdb.BinaryQueryParams{
    QueryVectors: [][]float32{
        {0.1, 0.2, 0.3, 0.4},
        {0.5, 0.6, 0.7, 0.8},
    },
    TopK: 1,
})
if err != nil {
    log.Fatal(err)
}
fmt.Println(len(*resp.Results.ArrayOfArrayOfQueryResultItem))
// Output: 2
```

#### Text, embedded by the service

```go theme={null}
// The index must have been created with EmbeddingModel
text := "machine learning in healthcare"

resp, err := index.Query(ctx, cyborgdb.QueryParams{QueryContents: &text, TopK: 3})
if err != nil {
    log.Fatal(err)
}
for _, r := range *resp.Results.ArrayOfQueryResultItem {
    fmt.Println(r.Id)
}
```

#### Hybrid (BM25 + vector)

The index needs at least one full-text field, set with `TextFields` or `FullText` in [`CreateIndex`](../client/create-index#metadata-schema).

```go theme={null}
text := "encrypted search"
alpha := 0.5

resp, err := index.Query(ctx, cyborgdb.QueryParams{
    QueryVector: []float32{0.1, 0.2, 0.3, 0.4},
    Text:        &text,
    Alpha:       &alpha,
    TopK:        2,
    Include:     []string{"metadata"},
})
if err != nil {
    log.Fatal(err)
}

for _, r := range *resp.Results.ArrayOfQueryResultItem {
    fmt.Printf("%s %.4f\n", r.Id, r.GetScore())
}
// Output:
// doc1 0.0164
// doc2 0.0161
```

#### Filters and search options

```go theme={null}
nProbes := int32(5)
rerankMult := int32(20)
greedy := true

resp, err := index.Query(ctx, cyborgdb.QueryParams{
    QueryVector: []float32{0.1, 0.2, 0.3, 0.4},
    TopK:        20,
    NProbes:     &nProbes,
    RerankMult:  &rerankMult,
    Greedy:      &greedy,
    Filters:     map[string]interface{}{"category": "news"},
    Include:     []string{"distance", "metadata"},
})
if err != nil {
    log.Fatal(err)
}

for _, r := range *resp.Results.ArrayOfQueryResultItem {
    fmt.Println(r.Id, r.Metadata["category"])
}
// Output: doc1 news
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.