Add filter methods before you run the query. Several filters combine with and. Filters are sent to the server and applied by the database, so you only download what matches.

The filters

In Python, in_ and is_ have a trailing underscore because in and is are keywords. eq("x", null) is rejected: nothing equals null. Use is("x", null) and isNot("x", null).

Conditions as an object

A plain value means equal. An object picks an operator: eq, neq, gt, gte, lt, lte, like, ilike, in, nin, is, isnot.

Dates

Pass a Date (TypeScript) or datetime (Python), or an ISO 8601 string. Times are UTC.

Empty lists

in("id", []) returns nothing at once, without a request. That is what you want when a list of ids is empty.

Search boxes

Debounce the input so you don’t send a query on every key press, and cancel the previous query with an AbortSignal. Escape % and _ in the term, since they are pattern characters. For real full-text search across many columns, a route backed by a database full-text query is better than ilike.

Combining “or”

Chained filters are all “and”. For “or”, use in for several values of one column, or two queries merged in your app, or a route for complex logic:

Filters and access rules

Filters narrow what you ask for. Access rules decide what you are allowed to see. A filter can never reveal a row a rule hides: asking for owner_id = someone else just returns nothing. Likewise a rule can’t be bypassed by a clever filter.

Make filters fast

Filter on indexed columns. A filter on an unindexed column in a table of millions of rows scans it. If a list is slow, check the filter columns first.

Sort and page

Order the results.

Indexes

Keep filters fast.