Skip to content

Selectors: Patterns, Arrays, and Relationships

This page covers DartQL’s pattern matching, array operators, and relationship queries. For basic syntax, operators, and field reference, see the Syntax Reference.

LIKE uses SQL-92 wildcards for case-insensitive text matching:

WildcardMeaningExampleMatches
%Any sequence of characters (including none)title LIKE 'Task%'”Task”, “Task 1”, “Task: deploy”
_Exactly one charactertitle LIKE 'v_.0'”v1.0”, “v2.0” but not “v10.0”

Starts with:

title LIKE 'API%'

Ends with:

title LIKE '%fix'

Contains substring:

title LIKE '%authentication%'

Single character wildcard:

description LIKE 'API_%'
-- Matches "API_v1", "API_v2" but not "API" (underscore requires one character)

Combine wildcards:

title LIKE 'v_.__%'
-- Matches "v1.0", "v2.10", "v3.0-beta" but not "v10.0"

CONTAINS (and its aliases INCLUDES and HAS) checks whether an array field includes a specific value.

-- Tasks tagged "urgent"
tags CONTAINS 'urgent'
-- Tasks tagged both "bug" AND "security"
tags CONTAINS 'bug' AND tags CONTAINS 'security'
-- Tasks tagged either "bug" OR "feature"
tags CONTAINS 'bug' OR tags CONTAINS 'feature'

CONTAINS works with all relationship array fields to find tasks connected to a specific task ID.

Find tasks blocked by a specific task:

blocker_ids CONTAINS 'duid_release_blocker'

Find tasks that block a specific task:

blocking_ids CONTAINS 'duid_deployment'

Find related tasks:

related_ids CONTAINS 'duid_feature_spec'

Use IS NULL and IS NOT NULL to find tasks based on whether they have relationships. Empty arrays [] are treated as NULL.

Find blocked tasks (tasks that have blockers):

blocker_ids IS NOT NULL

Find tasks that are blocking others:

blocking_ids IS NOT NULL

Find parent tasks (tasks that have subtasks):

subtask_ids IS NOT NULL

Find leaf tasks (no subtasks):

subtask_ids IS NULL

Find tasks with duplicates:

duplicate_ids IS NOT NULL

Combining Relationships with Other Filters

Section titled “Combining Relationships with Other Filters”
-- High-priority blocked tasks
blocker_ids IS NOT NULL AND priority = 4
-- Blocked tasks in a specific dartboard
dartboard = 'Engineering/backend' AND blocker_ids IS NOT NULL
-- Critical tasks blocking a release
priority = 5 AND blocking_ids CONTAINS 'duid_release_v2'
-- Parent tasks with urgent tag
subtask_ids IS NOT NULL AND tags CONTAINS 'urgent'
-- Unblocked tasks ready to start
blocker_ids IS NULL AND status = 'To Do' AND priority = 4

IN is cleaner than chaining OR when checking a field against several values:

-- Instead of: status = 'To Do' OR status = 'Doing' OR status = 'Blocked'
status IN ('To Do', 'Doing', 'Blocked')
-- Exclude specific priorities
priority NOT IN (1, 2)

Many task fields are optional. Use IS NULL to find tasks missing data:

-- Tasks without a due date
due_at IS NULL
-- Tasks that have an assignee
assignee IS NOT NULL
-- Unstarted tasks (no start date set)
start_at IS NULL

DartQL queries are fastest when they use API-compatible filters. See Query Performance in the Syntax Reference for the full breakdown.

Fast pattern — equality with AND:

status = 'To Do' AND dartboard = 'Engineering/backend' AND priority = 4

Slower pattern — OR, LIKE, CONTAINS, and other advanced operators require client-side filtering:

title LIKE '%deploy%' OR tags CONTAINS 'infrastructure'

When mixing fast and slow filters, dart-query pushes the API-compatible parts to the server and applies the rest client-side. Put your most selective API-compatible conditions first to minimize the data fetched:

-- Good: dartboard and status narrow the API query; LIKE filters client-side
dartboard = 'Engineering/backend' AND status = 'Doing' AND title LIKE '%deploy%'