# `Aerospike.Query`
[🔗](https://github.com/luisgabrielroldan/aerospike_driver/blob/v0.3.1/lib/aerospike/query.ex#L1)

Composable query description with separate predicate lanes.

The query itself is pure data. It does not own transport state or
partition iteration.

Query execution lives in explicit facade calls such as
`Aerospike.query_stream/3`, `Aerospike.query_aggregate/6`,
`Aerospike.query_aggregate_result/6`, `Aerospike.query_execute/4`, and
`Aerospike.query_udf/6`.
Node-targeted execution uses `node: node_name` in facade opts where that
query helper supports it. Discover valid names with
`Aerospike.node_names/1` or `Aerospike.nodes/1`. Finalized aggregate
queries do not support node targeting because they must consume every server
partial needed for one local final result. `query_all/3` and `query_page/3`
require `query.max_records`.

Use `where/2` for secondary-index predicates (`Aerospike.Filter`), and
`filter/2` for server-side expression filters (`Aerospike.Exp`). Both can be
used together where the query is supported.

# `bin_names`

```elixir
@type bin_names() :: [String.t()]
```

Bin names accepted by `select/2`.

# `t`

```elixir
@type t() :: %Aerospike.Query{
  bin_names: bin_names(),
  filters: [Aerospike.Exp.t()],
  index_filter: Aerospike.Filter.t() | nil,
  max_records: pos_integer() | nil,
  namespace: String.t(),
  no_bins: boolean(),
  partition_filter: Aerospike.PartitionFilter.t() | nil,
  records_per_second: non_neg_integer(),
  set: String.t()
}
```

Query description consumed by `Aerospike.query_*` helpers.

`index_filter` is the single secondary-index query filter. `filters` are
server-side filter expressions combined with boolean AND by the encoder.

# `filter`

```elixir
@spec filter(t(), Aerospike.Exp.t()) :: t()
```

Appends a server-side expression filter.

Multiple calls append additional expression filters that are combined with
server-side boolean AND when encoded.

# `max_records`

```elixir
@spec max_records(t(), pos_integer()) :: t()
```

Sets the maximum number of records to return.

`query_all/3` and `query_page/3` require this value on the query struct.
The final result or page may contain fewer records when partition progress
completes first.

# `new`

```elixir
@spec new(String.t(), String.t()) :: t()
```

Starts a query for a namespace and set.

Both namespace and set must be non-empty strings.

# `no_bins`

```elixir
@spec no_bins(t(), boolean()) :: t()
```

When `true`, the server omits bin payloads.

This is useful for count-like queries or key/header-only workflows.

# `partition_filter`

```elixir
@spec partition_filter(t(), Aerospike.PartitionFilter.t()) :: t()
```

Attaches a partition filter for partial queries or advanced resume.

The filter is usually built with `Aerospike.PartitionFilter.all/0`,
`by_id/1`, `by_range/2`, or restored from a page cursor.

# `records_per_second`

```elixir
@spec records_per_second(t(), non_neg_integer()) :: t()
```

Sets the records-per-second throttle.

`0` disables query-level throttling.

# `select`

```elixir
@spec select(t(), bin_names()) :: t()
```

Restricts returned bin names.

Passing an empty list keeps the server default of returning all bins unless
`no_bins/2` or execution opts request otherwise.

# `where`

```elixir
@spec where(t(), Aerospike.Filter.t()) :: t()
```

Sets the secondary-index predicate.

A query can carry one secondary-index predicate. Calling `where/2` again
replaces the prior predicate.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
