Filter Operators
Filters are JSON objects passed to search endpoints. They compose with and, or, and not to form arbitrarily complex queries.
ThogitFilter Operators
Section titled “ThogitFilter Operators”Top-level operators for filtering thogits.
| Operator | Format | Description |
|---|---|---|
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 |
Examples
Section titled “Examples”{ "search": "schema validation" }Matches thogits whose name or description contains “schema validation”.
{ "has_tag": "Project Tracker" }Matches thogits that have the “Project Tracker” tag applied.
{ "Project Tracker.story_points": { "gte": 5 } }Matches thogits where the story_points field on the “Project Tracker” tag is >= 5.
{ "Task.parent->Project.status": { "match": "Active" } }Follows the parent reference field on the “Task” tag to the target thogit, then checks the status field on the “Project” tag of that target.
{ "and": [ { "has_tag": "Project Tracker" }, { "Project Tracker.story_points": { "gte": 3 } }, { "or": [ { "Project Tracker.status": { "match": "Active" } }, { "Project Tracker.status": { "match": "Backlog" } } ]} ]}StringFilter Operators
Section titled “StringFilter Operators”Used with name and description fields on both ThogitFilter and TagFilter.
| Operator | Format | Description |
|---|---|---|
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 |
Examples
Section titled “Examples”// 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\\]" } }FieldValueFilter Operators
Section titled “FieldValueFilter Operators”Used in field predicates ("TagName.field": <FieldValueFilter>). The available operators depend on the field’s schema type.
Bare Value Shorthand
Section titled “Bare Value Shorthand”A bare value (not wrapped in an operator object) is shorthand for eq:
| Value | Equivalent | Applicable 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 } }String Operators
Section titled “String Operators”| Operator | Format | Description |
|---|---|---|
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
Equality Operators
Section titled “Equality Operators”| Operator | Format | Description |
|---|---|---|
eq | {"eq": value} | Equal to |
neq | {"neq": value} | Not equal to |
Works with: String, Number, Boolean, Date
Comparison Operators
Section titled “Comparison Operators”| Operator | Format | Description |
|---|---|---|
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" } }]}Existence Operators
Section titled “Existence Operators”| Operator | Format | Description |
|---|---|---|
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 } }Set Operators
Section titled “Set Operators”| Operator | Format | Description |
|---|---|---|
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] } }Select / MultiSelect Operators
Section titled “Select / MultiSelect Operators”| Operator | Format | Description |
|---|---|---|
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" } }Type Compatibility Matrix
Section titled “Type Compatibility Matrix”| Operator | String | Number | Boolean | Date | Reference | Select | MultiSelect |
|---|---|---|---|---|---|---|---|
eq | Yes | Yes | Yes | Yes | — | — | — |
neq | Yes | Yes | Yes | Yes | — | — | — |
contains | Yes | — | — | — | — | — | — |
starts_with | Yes | — | — | — | — | — | — |
matches | Yes | — | — | — | — | — | — |
gt / gte | — | Yes | — | Yes | — | — | — |
lt / lte | — | Yes | — | Yes | — | — | — |
in | Yes | Yes | — | Yes | — | — | — |
exists | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
is_null | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
match | — | — | — | — | — | Yes | Yes |
select_gt/gte/lt/lte | — | — | — | — | — | Yes | Yes |
TagFilter Operators
Section titled “TagFilter Operators”Used to filter tags (e.g., in tag search endpoints).
| Operator | Format | Description |
|---|---|---|
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 |
Examples
Section titled “Examples”// 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" } } }]}Composition
Section titled “Composition”All filter types support and, or, and not for arbitrary nesting.
| Combinator | Behavior |
|---|---|
and | All child filters must match. Short-circuits on first failure. |
or | At least one child filter must match. Short-circuits on first success. |
not | Inverts the child filter. |
{ "and": [ { "has_tag": "Task" }, { "not": { "Task.status": { "match": "Done" } } }, { "or": [ { "Task.priority": { "gte": 3 } }, { "Task.labels": { "match": "Urgent" } } ]} ]}