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

# Interface: Query<TableInfo>

> The Query interface allows functions to read values out of the database.

[server](/api/modules/server).Query

The [Query](/api/interfaces/server.Query) interface allows functions to read values out of the database.

**If you only need to load an object by ID, use `db.get(tableName, id)` instead.**

Executing a query consists of calling

1. (Optional) [order](/api/interfaces/server.Query#order) to define the order
2. (Optional) [filter](/api/interfaces/server.OrderedQuery#filter) to refine the results
3. A *consumer* method to obtain the results

Queries are lazily evaluated. No work is done until iteration begins, so constructing and
extending a query is free. The query is executed incrementally as the results are iterated over,
so early terminating also reduces the cost of the query.

**`Example`**

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
// Use .withIndex() for efficient queries (preferred over .filter()):
const messages = await ctx.db
  .query("messages")
  .withIndex("by_channel", (q) => q.eq("channelId", channelId))
  .order("desc")
  .take(10);

// Async iteration for processing large result sets:
for await (const task of ctx.db.query("tasks")) {
  // Process each task without loading all into memory
}

// Get a single unique result (throws if multiple match):
const user = await ctx.db
  .query("users")
  .withIndex("by_email", (q) => q.eq("email", email))
  .unique();
```

**Common mistake:** `.collect()` loads **all** matching documents into memory.
If the result set can grow unbounded as your database grows, this will
eventually cause problems. Prefer `.first()`, `.unique()`, `.take(n)`, or
pagination instead. Only use `.collect()` on queries with a tightly bounded
result set (e.g., items belonging to a single user with a known small limit).

| | |
| - | - |
| **Ordering** | |
| [`order("asc")`](#order) | Define the order of query results. |
| | |
| **Filtering** | |
| [`filter(...)`](#filter) | Filter the query results to only the values that match some condition. |
| | |
| **Consuming** | Execute a query and return results in different ways. |
| [`[Symbol.asyncIterator]()`](#asynciterator) | The query's results can be iterated over using a `for await..of` loop. |
| [`collect()`](#collect) | Return all of the results as an array. |
| [`take(n: number)`](#take) | Return the first `n` results as an array. |
| [`first()`](#first) | Return the first result. |
| [`unique()`](#unique) | Return the only result, and throw if there is more than one result. |

To learn more about how to write queries, see [Querying the Database](/database/reading-data/reading-data).

## Type parameters

| Name | Type |
| :- | :- |
| `TableInfo` | extends [`GenericTableInfo`](/api/modules/server#generictableinfo) |

## Hierarchy

* [`OrderedQuery`](/api/interfaces/server.OrderedQuery)\<`TableInfo`>

  ↳ **`Query`**

  ↳↳ [`QueryInitializer`](/api/interfaces/server.QueryInitializer)

  ↳↳ [`SelectableQuery`](/api/interfaces/server.SelectableQuery)

## Methods

### order

▸ **order**(`order`): [`OrderedQuery`](/api/interfaces/server.OrderedQuery)\<`TableInfo`>

Define the order of the query output.

Use `"asc"` for an ascending order and `"desc"` for a descending order. If not specified, the order defaults to ascending.

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `order` | `"asc"` \| `"desc"` | The order to return results in. |

#### Returns

[`OrderedQuery`](/api/interfaces/server.OrderedQuery)\<`TableInfo`>

***

### filter

▸ **filter**(`predicate`): [`Query`](/api/interfaces/server.Query)\<`TableInfo`>

Filter the query output, returning only the values for which `predicate` evaluates to true.

**Important:** Prefer using `.withIndex()` over `.filter()` whenever
possible. Filters scan all documents matched so far and discard non-matches,
while indexes efficiently skip non-matching documents. Define an index in
your schema for fields you filter on frequently.

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `predicate` | (`q`: [`FilterBuilder`](/api/interfaces/server.FilterBuilder)\<`TableInfo`>) => [`ExpressionOrValue`](/api/modules/server#expressionorvalue)\<`boolean`> | An [Expression](/api/classes/server.Expression) constructed with the supplied [FilterBuilder](/api/interfaces/server.FilterBuilder) that specifies which documents to keep. |

#### Returns

[`Query`](/api/interfaces/server.Query)\<`TableInfo`>

* A new [OrderedQuery](/api/interfaces/server.OrderedQuery) with the given filter predicate applied.

#### Inherited from

[OrderedQuery](/api/interfaces/server.OrderedQuery).[filter](/api/interfaces/server.OrderedQuery#filter)

***

### paginate

▸ **paginate**(`paginationOpts`): `Promise`\<[`PaginationResult`](/api/interfaces/server.PaginationResult)\<[`DocumentByInfo`](/api/modules/server#documentbyinfo)\<`TableInfo`>>>

Load a page of `n` results and obtain a [Cursor](/api/modules/server#cursor) for loading more.

Note: If this is called from a reactive query function the number of
results may not match `paginationOpts.numItems`!

`paginationOpts.numItems` is only an initial value. After the first invocation,
`paginate` will return all items in the original query range. This ensures
that all pages will remain adjacent and non-overlapping.

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `paginationOpts` | [`PaginationOptions`](/api/interfaces/server.PaginationOptions) | A [PaginationOptions](/api/interfaces/server.PaginationOptions) object containing the number of items to load and the cursor to start at. |

#### Returns

`Promise`\<[`PaginationResult`](/api/interfaces/server.PaginationResult)\<[`DocumentByInfo`](/api/modules/server#documentbyinfo)\<`TableInfo`>>>

A [PaginationResult](/api/interfaces/server.PaginationResult) containing the page of results and a
cursor to continue paginating.

#### Inherited from

[OrderedQuery](/api/interfaces/server.OrderedQuery).[paginate](/api/interfaces/server.OrderedQuery#paginate)

***

### collect

▸ **collect**(): `Promise`\<[`DocumentByInfo`](/api/modules/server#documentbyinfo)\<`TableInfo`>\[]>

Execute the query and return all of the results as an array.

**Warning:** This loads every matching document into memory. If the result
set can grow unbounded as your database grows, `.collect()` will eventually
cause performance problems or hit limits. Only use `.collect()` when the
result set is tightly bounded (e.g., a known small number of items).

Prefer `.first()`, `.unique()`, `.take(n)`, or `.paginate()` when the
result set may be large or unbounded. For processing many results without
loading all into memory, use the `Query` as an `AsyncIterable` with
`for await...of`.

#### Returns

`Promise`\<[`DocumentByInfo`](/api/modules/server#documentbyinfo)\<`TableInfo`>\[]>

* An array of all of the query's results.

#### Inherited from

[OrderedQuery](/api/interfaces/server.OrderedQuery).[collect](/api/interfaces/server.OrderedQuery#collect)

***

### take

▸ **take**(`n`): `Promise`\<[`DocumentByInfo`](/api/modules/server#documentbyinfo)\<`TableInfo`>\[]>

Execute the query and return the first `n` results.

#### Parameters

| Name | Type | Description |
| :- | :- | :- |
| `n` | `number` | The number of items to take. |

#### Returns

`Promise`\<[`DocumentByInfo`](/api/modules/server#documentbyinfo)\<`TableInfo`>\[]>

* An array of the first `n` results of the query (or less if the
  query doesn't have `n` results).

#### Inherited from

[OrderedQuery](/api/interfaces/server.OrderedQuery).[take](/api/interfaces/server.OrderedQuery#take)

***

### first

▸ **first**(): `Promise`\<`null` | [`DocumentByInfo`](/api/modules/server#documentbyinfo)\<`TableInfo`>>

Execute the query and return the first result if there is one.

#### Returns

`Promise`\<`null` | [`DocumentByInfo`](/api/modules/server#documentbyinfo)\<`TableInfo`>>

* The first value of the query or `null` if the query returned no results.

#### Inherited from

[OrderedQuery](/api/interfaces/server.OrderedQuery).[first](/api/interfaces/server.OrderedQuery#first)

***

### unique

▸ **unique**(): `Promise`\<`null` | [`DocumentByInfo`](/api/modules/server#documentbyinfo)\<`TableInfo`>>

Execute the query and return the singular result if there is one.

Use this when you expect exactly zero or one result, for example when
querying by a unique field. If the query matches more than one document,
this will throw an error.

**`Example`**

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
const user = await ctx.db
  .query("users")
  .withIndex("by_email", (q) => q.eq("email", "alice@example.com"))
  .unique();
```

**`Throws`**

Will throw an error if the query returns more than one result.

#### Returns

`Promise`\<`null` | [`DocumentByInfo`](/api/modules/server#documentbyinfo)\<`TableInfo`>>

* The single result returned from the query or null if none exists.

#### Inherited from

[OrderedQuery](/api/interfaces/server.OrderedQuery).[unique](/api/interfaces/server.OrderedQuery#unique)

***

### \[asyncIterator]

▸ **\[asyncIterator]**(): `AsyncIterator`\<[`DocumentByInfo`](/api/modules/server#documentbyinfo)\<`TableInfo`>, `any`, `undefined`>

#### Returns

`AsyncIterator`\<[`DocumentByInfo`](/api/modules/server#documentbyinfo)\<`TableInfo`>, `any`, `undefined`>

#### Inherited from

[OrderedQuery](/api/interfaces/server.OrderedQuery).[\[asyncIterator\]](/api/interfaces/server.OrderedQuery#\[asynciterator])
