Skip to content

Filter Operators

Filters are JSON objects passed to search endpoints. They compose with and, or, and not to form arbitrarily complex queries.

Top-level operators for filtering thogits.

OperatorFormatDescription
search{"search": "text"}Full-text search on name + description
name{"name": <StringFilter>}Filter on thogit name
description{"description": <StringFilter>}Filter on description
has_tag{"has_tag": "TagName"} or {"has_tag": "ULID"}Tag presence check (by name or ID)
has_field{"has_field": {"tag": "TagName", "key": "field"}}Field presence check (non-null value)
field predicate{"TagName.field": <FieldValueFilter>}Field value check using dot notation
reference traversal{"Tag.ref->Target.field": <op>}Follow a reference field, filter the target’s field
and{"and": [f1, f2, ...]}All conditions must match
or{"or": [f1, f2, ...]}Any condition can match
not{"not": <filter>}Negation
{ "search": "schema validation" }

Matches thogits whose name or description contains “schema validation”.


Used with name and description fields on both ThogitFilter and TagFilter.

OperatorFormatDescription
contains{"contains": "text"}Case-sensitive substring match
equals / eq{"equals": "text"} or {"eq": "text"}Exact string match
starts_with{"starts_with": "prefix"}Prefix match
matches{"matches": "^regex$"}Regular expression match
neq{"neq": "text"}Not equal to
// Thogits whose name contains "sprint"
{ "name": { "contains": "sprint" } }
// Thogits whose name starts with "2024-"
{ "name": { "starts_with": "2024-" } }
// Thogits whose description matches a regex
{ "description": { "matches": "^\\[DRAFT\\]" } }

Used in field predicates ("TagName.field": <FieldValueFilter>). The available operators depend on the field’s schema type.

A bare value (not wrapped in an operator object) is shorthand for eq:

ValueEquivalentApplicable types
"text"{"eq": "text"}String
42{"eq": 42}Number
true{"eq": true}Boolean
null{"is_null": true}All types
// These are equivalent:
{ "Project.priority": 3 }
{ "Project.priority": { "eq": 3 } }
OperatorFormatDescription
eq{"eq": "value"}Exact match
neq{"neq": "value"}Not equal
contains{"contains": "text"}Substring match
starts_with{"starts_with": "prefix"}Prefix match
matches{"matches": "regex"}Regular expression match

Works with: String fields

OperatorFormatDescription
eq{"eq": value}Equal to
neq{"neq": value}Not equal to

Works with: String, Number, Boolean, Date

OperatorFormatDescription
gt{"gt": value}Greater than
gte{"gte": value}Greater than or equal
lt{"lt": value}Less than
lte{"lte": value}Less than or equal

Works with: Number, Date

// Numbers
{ "Project.story_points": { "gt": 5 } }
// Dates
{ "Project.due_date": { "lt": "2024-12-31" } }
// Date range (combine with and)
{ "and": [
{ "Project.due_date": { "gte": "2024-01-01" } },
{ "Project.due_date": { "lte": "2024-12-31" } }
]}
OperatorFormatDescription
exists{"exists": true}Field value is present and not null
exists{"exists": false}Field value is null or missing
is_null{"is_null": true}Field value is null or missing

Works with: All field types

// Thogits where due_date is set
{ "Project.due_date": { "exists": true } }
// Thogits where due_date is not set
{ "Project.due_date": { "is_null": true } }
OperatorFormatDescription
in{"in": [v1, v2, ...]}Value is one of the given values

Works with: String, Number, Date

{ "Project.story_points": { "in": [1, 2, 3, 5, 8] } }
OperatorFormatDescription
match{"match": "Variant"}Has this variant selected
select_gt{"select_gt": "Variant"}Ordinal position > given variant
select_gte{"select_gte": "Variant"}Ordinal position >= given variant
select_lt{"select_lt": "Variant"}Ordinal position < given variant
select_lte{"select_lte": "Variant"}Ordinal position <= given variant

Works with: Select, MultiSelect fields

// Thogits with status = Active
{ "Project.status": { "match": "Active" } }
// Thogits not yet Done (Backlog or Active)
{ "Project.status": { "select_lt": "Done" } }
// MultiSelect: thogits labeled "Bug"
{ "Project.labels": { "match": "Bug" } }
OperatorStringNumberBooleanDateReferenceSelectMultiSelect
eqYesYesYesYes
neqYesYesYesYes
containsYes
starts_withYes
matchesYes
gt / gteYesYes
lt / lteYesYes
inYesYesYes
existsYesYesYesYesYesYesYes
is_nullYesYesYesYesYesYesYes
matchYesYes
select_gt/gte/lt/lteYesYes

Used to filter tags (e.g., in tag search endpoints).

OperatorFormatDescription
search{"search": "text"}Full-text search on tag name + description
name{"name": <StringFilter>}Filter on tag name (uses StringFilter operators)
description{"description": <StringFilter>}Filter on tag description
and{"and": [f1, f2, ...]}All conditions must match
or{"or": [f1, f2, ...]}Any condition can match
not{"not": <filter>}Negation
// Tags whose name contains "project"
{ "name": { "contains": "project" } }
// Tags with "tracker" in name or description
{ "search": "tracker" }
// Combine filters
{ "and": [
{ "name": { "starts_with": "Project" } },
{ "not": { "name": { "eq": "Project Archive" } } }
]}

All filter types support and, or, and not for arbitrary nesting.

CombinatorBehavior
andAll child filters must match. Short-circuits on first failure.
orAt least one child filter must match. Short-circuits on first success.
notInverts the child filter.
{
"and": [
{ "has_tag": "Task" },
{ "not": { "Task.status": { "match": "Done" } } },
{ "or": [
{ "Task.priority": { "gte": 3 } },
{ "Task.labels": { "match": "Urgent" } }
]}
]
}