Filtering records
Every view filter operator, its value shape, the field kinds that accept it, and relative date resolution.
A filter keeps records that match a condition. Filters live on one view and do not change or secure the records. Use permissions when someone must not be able to retrieve the underlying data.
Each filter stores a field key, an operator, and a string value. Conditions at
the top level use and or or; one level of filter groups may choose its own
conjunction. Filters run before grouping and sorting.
Canonical contract values:
containsdoes_not_containisis_notis_emptyis_not_emptyequalsnot_equalsgreater_thanless_thanbeforeafteris_withinis_checkedis_unchecked
Operators
Contains contains
For ordinary fields, performs a case-insensitive substring check on the formatted value. For Multi-select and Relation, the value is one exact option key or related record UUID and the operator tests membership instead. A User or File value is compared through its formatted stored value, not a nested property.
Does not contain does_not_contain
Negates Contains. For Multi-select and Relation, it passes when the exact option or record UUID is absent. For text-like values, it passes when the case-insensitive substring is absent.
Is is
Tests equality. Select and Status values are option keys selected by the
editor. Relation equality means the relation has exactly one target and it is
the supplied record UUID; use Contains for membership in a many-valued
relation. Date is compares the local calendar day, not the timestamp’s exact
milliseconds.
Is not is_not
Negates Is. On a relation, a value with zero, two, or more links is therefore “not” any single target. On general formatted values the comparison is case-insensitive as well as checking the raw stored string.
Is empty is_empty
Needs no value. Empty means null, undefined, an empty string, or an empty
array. For Date, a range is empty when it has no start. false, 0, and an
empty JSON object are values, not empty. Button has no stored value, so this is
the only practically useful positive filter on that kind.
Is not empty is_not_empty
Needs no value and negates Is empty. It does not mean truthy: unchecked checkboxes and numeric zero are still not empty.
Equals equals
Compares Number or Time tracking numerically. The filter value is a decimal number encoded as a string; time-tracking controls convert human minutes to the stored millisecond number.
Not equals not_equals
Numeric inequality for Number and Time tracking. An invalid numeric filter is treated as non-restricting rather than matching no records, and the editor normally prevents such a value.
Greater than greater_than
Keeps numeric or duration values greater than the supplied number. This is a strict comparison; equal values do not pass.
Less than less_than
Keeps numeric or duration values below the supplied number. This is also strict.
Before before
Compares the start of Date ranges, Created at, or Updated at with a literal date
or the relative day token today, yesterday, or tomorrow. A timestamp must
be strictly earlier to pass.
After after
The date counterpart to Before. It uses a range’s start and requires a strictly later timestamp.
Is within is_within
Accepts one rolling range token: past_week, past_month, past_year,
next_week, next_month, or next_year. The bounds are inclusive. It does
not accept an arbitrary start/end pair in the current view filter contract.
Is checked is_checked
Needs no value and passes only when a Checkbox stores true.
Is unchecked is_unchecked
Needs no value and passes only when a Checkbox stores false. Newly created
records normally have the intrinsic unchecked value.
Operators by field kind
This table is generated by asking the same contract predicate used to validate view filters. Formula and Rollup currently receive the general formatted-value set even when their declared result kind is numeric, date, or checkbox.
| Field kind | Accepted operators |
|---|---|
text | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
long_text | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
number | is_empty, is_not_empty, equals, not_equals, greater_than, less_than |
rating | is_empty, is_not_empty, equals, not_equals, greater_than, less_than |
date | is, is_empty, is_not_empty, before, after, is_within |
select | is, is_not, is_empty, is_not_empty |
multi_select | contains, does_not_contain, is_empty, is_not_empty |
status | is, is_not, is_empty, is_not_empty |
checkbox | is_empty, is_not_empty, is_checked, is_unchecked |
url | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
email | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
phone | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
user | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
file | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
place | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
json | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
created_at | is, is_empty, is_not_empty, before, after, is_within |
created_by | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
updated_at | is, is_empty, is_not_empty, before, after, is_within |
updated_by | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
unique_id | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
formula | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
relation | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
rollup | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
time_tracking | is_empty, is_not_empty, equals, not_equals, greater_than, less_than |
button | contains, does_not_contain, is, is_not, is_empty, is_not_empty |
The table describes accepted manifest operators. Acceptance does not guarantee a useful stored value: Button stores none, for example, so its general text operators normally see an empty string.
Relative date resolution
today, yesterday, and tomorrow resolve whenever the filter is evaluated.
The evaluator starts at local midnight and moves by a local calendar day, so
the answer follows the environment doing the evaluation rather than storing a
fixed timestamp in the view.
The range tokens are rolling windows anchored at the current instant:
- week means exactly 7 days;
- month means exactly 30 days;
- year means exactly 365 days;
past_*covers now minus that duration through now;next_*covers now through now plus that duration.
These are not calendar-week, calendar-month, or calendar-year boundaries. A
view using next_month changes continuously as time advances.
Values and failure behaviour
Option-bearing fields use stable option keys even though the editor displays names. User, File, and Relation filters use UUIDs. Text operators take literal text. Date operators accept parseable date strings or the tokens above.
Operators that require a value but receive an empty or invalid value are non-restricting in the shared engine. A filter for a field key that no longer exists also passes every record. This keeps a stale view readable, but it means an API-authored malformed filter does not fail closed; inspect the saved filter when a view looks unexpectedly broad.