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:

  • id
  • label
  • path
  • node-type
  • node-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

OperatorSyntaxMeaning
:field:valueCase-insensitive substring match on one field
~field~valueIdentical to :
=field=valueExact, case-sensitive equality for strings
!=field!=valueExact inequality for a present scalar value
>field>valueNumeric comparison for numbers; lexicographic for strings
<field<valueNumeric comparison for numbers; lexicographic for strings
>=field>=valueGreater than or equal
<=field<=valueLess than or equal
..field:min..maxInclusive range on a numeric field
containsfield contains valueCase-insensitive substring match on a string or any scalar array element
has:has:fieldField is present and not null
missing:missing:fieldField is absent, undefined, or null
empty:empty:fieldField is present and is a blank string or empty array
ANDa AND bBoth expressions must match
ORa OR bEither expression may match

Keywords are case-insensitive. Field names and string equality are case-sensitive; :/~ and contains values are case-insensitive.

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, or 1.5. Strings such as "12ms" are not coerced to numbers.
  • String fields use exact, case-sensitive equality or lexicographic ordering.
  • Boolean fields support = and != with true or false.
  • 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 not null; an empty string or empty array still counts as present.
  • missing: means absent, undefined, or null.
  • 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:

  1. Parentheses
  2. AND
  3. OR

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 ~ for node-type, literal node-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.