DSL Syntax
Complete reference for Schematify's search query language
The Graph Viewer search panel accepts typo-tolerant free text and a field-aware query language. For a workflow-oriented introduction, see Search and DSL.
Searchable fields
Root fields
These built-in fields are searchable on every node:
idlabelpathnode-typenode-status.type
node-status.type includes only literal string values stored in the graph document. A status supplied by a channel or attribute parameter binding is not copied into this field. You can query its declared source channel explicitly with channels.<key>.
Attribute fields
User-defined fields must use the attributes. prefix:
attributes.owner
attributes.region
attributes.cpu_cores
attributes.tags
For example, use attributes.owner:alice, not owner:alice. Arbitrary nested paths and bracket notation are not supported, and search does not inspect fields inside an attribute object.
Channel fields
Realtime channel fields use the channels. prefix:
channels.health
channels.latency
channels.tags
A channel field exists only on nodes that declare that key. Search uses the value shown by the renderer: a fresh received value, otherwise the channel’s default, otherwise a missing value. All normal string, number, boolean, array, range, and existence operators apply.
Operator reference
| Operator | Syntax | Meaning |
|---|---|---|
: | field:value | Case-insensitive substring match on one field |
~ | field~value | Identical to : |
= | field=value | Exact, case-sensitive equality for strings |
!= | field!=value | Exact inequality for a present scalar value |
> | field>value | Numeric comparison for numbers; lexicographic for strings |
< | field<value | Numeric comparison for numbers; lexicographic for strings |
>= | field>=value | Greater than or equal |
<= | field<=value | Less than or equal |
.. | field:min..max | Inclusive range on a numeric field |
contains | field contains value | Case-insensitive substring match on a string or any scalar array element |
has: | has:field | Field is present and not null |
missing: | missing:field | Field is absent, undefined, or null |
empty: | empty:field | Field is present and is a blank string or empty array |
AND | a AND b | Both expressions must match |
OR | a OR b | Either expression may match |
Keywords are case-insensitive. Field names and string equality are case-sensitive; :/~ and contains values are case-insensitive.
Free-text search
A query without DSL syntax searches scalar root fields and attributes. It never searches channel values. Use a channels.<key> predicate for realtime data.
api
databse
customer gateway
Free-text search starts at two characters. A two-character query performs case-insensitive substring matching; typo-tolerant ranking begins at three characters. Field-specific : and ~ queries are always substring matches, not fuzzy matches.
Field substring matching
Use : or ~; the operators are equivalent:
label:API
node-type~service
attributes.owner:alice
attributes.tags:critical
channels.health:critical
For arrays, a node matches when any scalar element contains the requested text.
Equality and comparisons
node-type=service
attributes.environment=production
attributes.replicas>=3
attributes.priority!=1
channels.latency>500
Comparisons are strict and type-aware:
- Numeric fields compare only against a complete numeric literal such as
3,-2, or1.5. Strings such as"12ms"are not coerced to numbers. - String fields use exact, case-sensitive equality or lexicographic ordering.
- Boolean fields support
=and!=withtrueorfalse. - Missing values and objects do not satisfy comparisons.
Quotes group a value but do not change its type or matching semantics.
Numeric ranges
Ranges are inclusive and work only on actual numeric fields:
attributes.cpu_cores:4..16
attributes.priority~1..3
channels.latency:100..500
Both : and ~ introduce the same range syntax. Date strings and numeric-looking strings are not numeric ranges.
Existence and emptiness
has:attributes.owner
missing:attributes.region
empty:attributes.description
missing:channels.version
The checks are deliberately distinct:
has:means present and notnull; an empty string or empty array still counts as present.missing:means absent,undefined, ornull.empty:means present but blank: a whitespace-only string or an empty array.
Contains
contains performs the same case-insensitive substring test for strings and individual scalar array elements:
attributes.tags contains critical
attributes.owner contains acme
label contains API
channels.tags contains api
Compound expressions and precedence
Combine expressions with AND and OR. Parsing follows conventional precedence:
- Parentheses
ANDOR
Repeated operators associate left-to-right. x AND y OR z means (x AND y) OR z, while x OR y AND z means x OR (y AND z).
Use parentheses whenever grouping should be explicit:
(node-type:server OR node-type:database) AND attributes.region:us-east
node-type:service AND (attributes.owner:alice OR attributes.owner:bob)
Parentheses may be nested up to 32 levels.
Quoting and escaping
Use double quotes around values containing spaces, parentheses, or reserved words:
label:"Customer API"
attributes.description:"contains AND operator"
label:"API (legacy)"
Inside a quoted value, escape a quote as \" and a backslash as \\. Quoting only groups characters; label:"API" is still a substring query, while label="API" is exact equality.
Validation and diagnostics
The search input reports positioned errors and warnings while you type:
- Unclosed quotes or parentheses, missing operands or values, invalid operators, and invalid ranges are errors.
- Unknown root fields are errors.
- An
attributes.*field not present in the current graph is a warning. It currently selects no nodes, but the query may still be saved as a smart filter because a later graph update can introduce that attribute. - A
channels.*predicate selects only nodes that declare that channel key. If no current node declares it, the valid query selects no nodes. - Invalid queries never execute and cannot create smart filters.
Queries are limited to 1,000 characters, 512 tokens, and 32 nested parenthesis groups.
Autocomplete
Autocomplete suggests:
- Built-in fields, discovered attribute fields, and declared channel fields.
- Known values after
:or~fornode-type, literalnode-status.type, and sufficiently repeated low-cardinality string attributes.
Suggestions are derived from the current graph. Channel values are never offered as value suggestions. High-cardinality and sparsely populated attributes intentionally do not offer value suggestions. Values containing spaces or reserved words are quoted automatically.
Examples
Production services owned by either team:
node-type:service AND attributes.environment=production AND (attributes.owner:platform OR attributes.owner:infrastructure)
Numeric capacity check:
attributes.cpu_cores>=8 OR attributes.memory_gb>=32
Audit incomplete metadata:
missing:attributes.owner OR empty:attributes.description
Tagged databases in a region:
node-type:database AND attributes.tags contains critical AND attributes.region:eu-west
Services with a current critical health channel:
channels.health=critical
Smart filters and saved views
The search panel can turn a valid query into an isolate, add-hidden, or exclude smart filter. Interactive search and smart filters use the same query semantics. They re-evaluate when the graph document changes, when a realtime channel batch arrives, and when a channel becomes stale.
When stale-after expires, channel queries fall back to the declared default or to a missing value without waiting for another event.
Bookmarks and compressed URL view state preserve smart-filter queries. Schematify automatically preserves the grouping of queries saved by older versions. If a historical query is no longer valid, it remains visible with an error and selects no nodes rather than silently changing meaning.
What’s next
- Search and DSL shows how to use queries for navigation and smart filters.
- Filtering explains how smart filters compose with node filters.
- Bookmarks covers saving filtered views.