Skip to main content
Answers are data. A query filters, sorts and ranks on answers as on any other field. A query can also read only the answers that are current. It can find the answers that one version of a judgment or an engine made. For example, this query finds the payments that have a settles pick. It ranks them by escape_p, the lowest first. It returns only current answers:
POST /v1/namespaces/acme%2Fprod/query
  • settles is the judgment that matches a payment to an open invoice. See match one record to another.
  • The unmatched threshold is true when escape_p, the probability of no match, is at least 0.3. Thus, the filter keeps the payments with a pick.
  • Each row has its id, its revision, the block attribute and the settles answer.

Filters

A filter is one of these:
  • [field, op, value];
  • ["And", [...]] or ["Or", [...]];
  • ["Not", filter].
The operators are Eq, NotEq, In, NotIn, Lt, Lte, Gt, Gte, Glob, Contains (on arrays of strings) and Exists. A comparison on a missing field is false. NotEq and NotIn on a missing field are true. Thus, ["answers.settles.value", "NotEq", "none_of_the_above"] also matches the payments that have no answer yet. To leave those payments out, add ["answers.settles.value", "Exists", true].

Fields you can filter on

You can filter on id, revision, updated_at and attributes.*. You cannot filter on state. For each judgment, you can also filter on these fields of its answer, as answers.<j>.<field>:

Find the answers of one version

judgment_version and engine_version find the answers that one version of the judgment or of the engine made. For example, you activate version 4 of settles. This filter finds the answers that versions 1 to 3 made:
  • judgment_version is an integer. Compare it with Eq, NotEq, Lt, Lte, Gt, Gte, In or NotIn, or test it with Exists.
  • engine_version is a string. For an engine version that is not pinned, such as jev current or gpt-6-luna current, it holds the label of the epoch, a period in which the engine’s behaviour stays the same, such as current+2026-09-24.1. Compare it with Eq, NotEq, In or NotIn, or test it with Exists. The label does not name the engine. Each engine numbers its own epochs, so two engines can have the same label. A query cannot filter on the engine’s name. A judgment changes its engine only in a new version, so filter on judgment_version as well.
  • You can also rank on both fields.
An answer from an earlier version of the judgment reads stale, with stale_reason older_version. A new engine version, such as a new epoch of an engine version that is not pinned, never makes an answer stale. Thus, to compare the answers of two epochs, filter on engine_version. See versions.

Filter on a feature

A feature filter names the judgment and the feature. For example, a judgment invoice_settlement keeps matched_payments.count as a feature. This filter finds the invoices with two or more matched payments:
  • All text after features. is the name of the feature. It must be a feature of that judgment.
  • You can compare it with numbers (Eq, NotEq, Lt, Lte, Gt, Gte, In, NotIn), or test it with Exists.
  • The filter reads the value stored with the answer. That value follows the related documents after the judgment’s debounce.
  • A window counts back from the document’s newest activity, not from today.
  • If freshness matters, also check the answer’s freshness.

Read only current answers

Each answer has a freshness. A query can use it in two ways:
  • answers: "fresh_only" removes each row whose included answers are not fresh. It checks only the judgments that include.answers names. A row with no answer for one of those judgments is also removed.
  • A filter on freshness reads one judgment’s freshness. For example, ["answers.settles.freshness", "Eq", "fresh"].
fresh_only and a filter on fresh leave out an answer from an earlier version of the judgment, because that answer reads stale. A filter on pending tells you if a judgment has caught up with your writes. A query for one pending answer returns no row when it has. A judgment’s judged_through tells you too, and reads no documents. See is a judgment caught up?.

Rank and page

  • rank_by is one field and a direction. The default is ["updated_at", "desc"]. Brussle breaks ties by id.
  • top_k is at most 1,000. more: true means that more rows matched.
  • cursor gets the next page. Send the next_cursor of the previous page. A cursor lasts 10 minutes. It keeps the namespace as it was at the first page. Thus, all pages agree with each other.
  • consistency: "eventual" can serve a view of the namespace up to 60 seconds old, for lower latency. The default is strong, which sees each write that Brussle acknowledged before the query.
  • Large scans are refused. If the estimated scan of a query is more than 4 GB, Brussle refuses it with too_large and the estimate. Brussle does not bill it. Add attribute filters to make the scan smaller.
Some filters read every document in the namespace, such as a filter on pending. See tradeoffs for which filters are fast.

Which judgments you can filter on

You can filter or rank on any judgment except an on_read judgment.
  • An on_read answer exists only after something reads it. A filter on an on_read judgment returns invalid_request. To filter on it, switch it to on_change first. Brussle then backfills the missing answers after you confirm an estimate. Brussle never backfills without your confirmation.
  • on_change keeps each answer current. Use this policy for the judgments that you filter on.
  • Filters read periodic and manual answers as they are stored.

Read one document

GET /namespaces/{ns}/documents/{id} returns one document with all its answers, and their history on request. See reading documents.

Count answers per group

A query returns documents. To count answers for each value of a key, such as the matched payments for each customer each month, declare a group. A group keeps counts, sums and averages over documents and answers for each key value. You read its rows when you want them.

Get told when a document matches

A subscription is a saved query. It sends an event when a document starts or stops matching its filter. Its filter uses the grammar on this page, except freshness.