BUCKET.QUERY
Queries documents from a bucket using a filter expression.
Syntax
Section titled “Syntax”BUCKET.QUERY <bucket> <query> [SORTBY <field> <ASC|DESC>] [RESULTSORT <field> <ASC|DESC>] [PROJECTION <spec>] [BATCH <n>] [LIMIT <n>] [COLLATION <spec>] [NAMESPACE <path>] [CLOSE]Arguments
Section titled “Arguments”Keyword names are not case-sensitive, and each keyword can appear at most once.
| Argument | Type | Required | Description |
|---|---|---|---|
bucket | string | Yes | Name of the bucket to query. |
query | JSON or BSON | Yes | Filter expression to match documents. Use {} to match all documents. |
SORTBY | string + direction | No | Sort results by a field. Requires field name followed by ASC or DESC. |
RESULTSORT | string + direction | No | Sort each result batch in memory by any field (indexed or not). Requires field name followed by ASC or DESC. Does not guarantee global ordering across BUCKET. calls. See RESULTSORT. |
PROJECTION | JSON or BSON | No | Projection specification that controls which fields appear in returned documents. Use {"field": 1} for inclusion or {"field": 0} for exclusion. See Projection. |
BATCH | integer | No | Maximum number of documents to return per batch. Must be non-negative. It does not cap the total number of results, use LIMIT for that. Use BUCKET. to get the next batch. When not specified, the session’s default batch size is used (default: 100, configurable via SESSION.). |
LIMIT | integer | No | Maximum total number of documents the cursor returns across the first call and all BUCKET. calls. Must be non-negative. 0 means no limit (default). When the limit is reached, the response carries cursor_id -1 and the cursor is removed. |
COLLATION | JSON | No | Query-level collation spec for locale-aware string comparison. Overrides index collation for this query. |
NAMESPACE | string | No | Run this command in the given namespace instead of the session’s current one. The namespace must exist. The session’s current namespace does not change. A cursor opened this way stays in that namespace for BUCKET.. |
CLOSE | flag | No | Close the cursor when the command returns. The response carries the first batch and cursor_id -1. Takes no value. |
Return Value
Section titled “Return Value”The command returns a cursor ID and matching documents. The format depends on the protocol version.
Each returned document includes an _id field (ObjectId) that serves as the document’s primary key.
The encoding format of returned documents depends on the session’s reply_type setting:
| Format | Response Type | Description |
|---|---|---|
bson | Binary | BSON-encoded document (default) |
json | String | JSON-encoded document |
To change the format:
SESSION.ATTRIBUTE SET reply_type bsonSESSION.ATTRIBUTE SET reply_type jsonRESP3 (map format):
The response is a map with two keys: cursor_id (integer) and entries (array of documents).
1# "cursor_id" => (integer) <cursor-id>2# "entries" => [<document-1>, <document-2>, ...]RESP2 (array format):
The response is an array with two elements: the cursor ID and a nested array of documents.
1) (integer) <cursor-id>2) 1) <document-1> 2) <document-2> ...Cursor ID:
The cursor ID is used to fetch more results with BUCKET.ADVANCE. Each query creates a new cursor that stores the query
context in the session.
The cursor tracks the position in the result set for pagination.
A cursor_id of -1 means the LIMIT was reached or the command was sent with CLOSE. The cursor no longer exists
and cannot be advanced.
Pagination
Section titled “Pagination”Results are returned in batches. Use the cursor ID with BUCKET.ADVANCE to get more results:
BUCKET.ADVANCE QUERY <cursor-id>When there are no more results, the command returns an empty result set.
BATCH caps a single call, LIMIT caps the whole cursor. Each call returns at most the smaller of BATCH and the
remaining LIMIT. The call that reaches the limit returns cursor_id -1 and removes the cursor from the session.
There is no need to call BUCKET.CLOSE on it. Without LIMIT, the cursor stays open until you close it.
When one batch is enough, send the command with CLOSE. The command returns the first batch with cursor_id -1
and leaves no cursor in the session.
The cursor maintains its state across calls:
- Query context (filter, sort, batch size, limit)
- Current position in the result set
- Transaction context (if within an explicit transaction)
Snapshot Reads
Section titled “Snapshot Reads”BUCKET.QUERY honors the session’s SNAPSHOTREAD setting. When SNAPSHOTREAD ON is active, index scans use snapshot
isolation, so they will not cause transactions to conflict with concurrent writes.
See SNAPSHOTREAD for details.
Routing
Section titled “Routing”The command must be sent to the primary of at least one shard assigned to the bucket. Any other member, including a
standby, rejects the request with a redirect to the primary. Use BUCKET.LOCATE to find it.
Errors
Section titled “Errors”Argument errors:
| Error Code | Error message | Cause |
|---|---|---|
ERR | BATCH argument must be followed by a non-negative integer | - |
ERR | LIMIT argument must be followed by a non-negative integer | - |
ERR | Unknown sort direction: '<value>' | The SORTBY direction is not ASC or DESC. |
ERR | Unknown '<keyword>' argument | - |
ERR | Duplicate '<keyword>' argument | - |
ERR | NAMESPACE argument must be followed by a namespace | - |
Namespace errors:
| Error Code | Error message | Cause |
|---|---|---|
NOSUCHNAMESPACE | No such namespace: '<path>' | - |
NAMESPACEBEINGREMOVED | Namespace '<path>' is being removed | - |
Bucket errors:
| Error Code | Error message | Cause |
|---|---|---|
NOSUCHBUCKET | No such bucket: '<bucket>' | - |
BUCKETBEINGREMOVED | Bucket '<bucket>' is being removed | - |
REJECT | <shardId> <host>:<port> | This member is not the primary of any of the bucket’s shards. The message carries the primary’s address. |
Examples
Section titled “Examples”The following examples assume reply_type is set to json.
Query all documents:
BUCKET.QUERY users '{}'Response (RESP3):
1# "cursor_id" => (integer) 12# "entries" => 1) {"_id": "6a240c7b5da17d872dc0e102", "name": "Bob", "age": 25, "status": "active"} 2) {"_id": "6a240c7b5da17d872dc0e103", "name": "Carol", "age": 35, "status": "inactive"} 3) {"_id": "6a240c875da17d872dc0e104", "name": "Henry", "age": 31, "scores": [75, 100, 100]}Query with filter:
BUCKET.QUERY users '{"name": "Alice"}'Query with sorting:
BUCKET.QUERY users '{}' SORTBY age DESCQuery with a batch size:
BUCKET.QUERY users '{"status": "active"}' BATCH 10Query with sorting and a batch size:
BUCKET.QUERY users '{"status": "active"}' SORTBY age ASC BATCH 5Query with a total limit:
BUCKET.QUERY users '{"status": "active"}' BATCH 10 LIMIT 25Returns at most 25 documents in total. The first two calls return 10 documents each, the third returns 5 with
cursor_id -1.
Query that closes its cursor:
> BUCKET.QUERY users '{"status": "active"}' BATCH 10 CLOSE1# "cursor_id" => (integer) -12# "entries" => [...] (first 10 documents)Query with projection:
BUCKET.QUERY users '{"status": "active"}' PROJECTION '{"name": 1, "email": 1}'Query with in-memory result sort (no index required):
BUCKET.QUERY users '{"status": "active"}' RESULTSORT score ASC BATCH 10Query with collation override:
BUCKET.QUERY users '{"name": "alice"}' COLLATION '{"locale": "en", "strength": 2}'This performs a case-insensitive match using English locale rules, regardless of the index’s collation setting.
Pagination:
> BUCKET.QUERY users '{}' BATCH 1001# "cursor_id" => (integer) 12# "entries" => [...] (first 100 documents)
> BUCKET.ADVANCE QUERY 11# "cursor_id" => (integer) 12# "entries" => [...] (next batch of documents)Pagination with a limit:
> BUCKET.QUERY users '{}' BATCH 2 LIMIT 31# "cursor_id" => (integer) 22# "entries" => [...] (2 documents)
> BUCKET.ADVANCE QUERY 21# "cursor_id" => (integer) -12# "entries" => [...] (1 document)
> BUCKET.ADVANCE QUERY 2(error) ERR No previous query context found for 'query' operation with the given cursor id