Skip to main content

Operator Precedence

Understanding operator precedence is crucial for writing correct DQL expressions. Operators with higher precedence are evaluated first. Use parentheses to override the default precedence. Examples:
DQL
When in doubt about precedence, use parentheses to make your intentions explicit. This improves code readability and prevents subtle bugs.

Arithmetic Operators

Arithmetic operators are used to perform operations on numeric values.

String Operators

Performs various operations on string scalar types:

Scalar Type Operators

Indicates which scalar type to interact with: Following is the mapping between data types and scalar types; all of which are case-sensitive:

Conversion Operators

Converts between different value types.

Array Operators

The following table provides an overview of interactions with array. Arrays can be either scalar values in a REGISTER or an input via an argument.

Date Operators

[1] Parts: year, mon/month, day, hour, min/minute, sec/second, ms/millis/millisecond.
[2] All in [1] plus: weekday (ISO-8601 - Monday is 1), monthname (English full month name only) & tz/timezone (string containing ±hh:mm).

Date format specification

Date formats may be specified using SQL-like representative syntax, or using strftime/date-like syntax with percent-sign introduced formatting specifiers (a.k.a. “percent-style”). If passed as an empty string, ISO-8601 format is assumed. e.g. 2026-01-31T22:15:30+02:00 The percent-style formatting is defined by the Rust chrono package:
  • Format specifiers
  • This format is similar to that used by the Unix/Linux date command.
  • Note that %.f and %.3f formats are equivalent as the date functions operate with millisecond precision and %.f essentially picks between %.3f (millisecond), %.6f (microsecond) and %.9f (nanosecond) based on the precision.
The common SQL-like style specifies the format using representative character sequences. Similar dialects can be found in many SQL implementations. All numeric fields in this format are zero-padded. The formatting sequences are: [1] 24-hour format only. For 12-hour format the percent style must be used.
[2] Since date functions do not operate on fractions beyond milliseconds, these formats can be considered aliases and be used interchangeably.

Examples

  • date_format(timestamp_ms,"") - convert an epoch millisecond value to an ISO-8601 string.
  • date_format(timestamp_ms,"YYYY-MM-DD") - extract just the date portion of an epoch millisecond timestamp value as a string.
  • date_format(timestamp_ms,"%T") - extract just the time portion of an epoch millisecond timestamp value as a string.

Object Operators

The following table provides an overview of interactions with object. Objects can be either scalar values in a REGISTER, MAP, Attachment, or an input via an argument.

object_content() Configuration

The object_content() function accepts configuration options to control output format: Configuration can be an object with optional fields:
  • output: 'fields' (default), 'keys', or 'values'
  • nested: 'no' (default), 'yes', or 'only'
  • subscripts: false (default) or true
Or individual strings:
  • 'fields', 'keys', 'values'
  • 'nested', 'nested-only'
  • 'subscripts'
Output modes:
  • fields: An array of objects each containing a single field & value pair
  • keys: An array of string keys (same as object_keys())
  • values: An array of values (same as object_values())
Nesting modes:
  • no / not specified: Don’t recursively process fields
  • nested/yes: Report the parent field then recursively process its contents
  • nested-only/only: Don’t report the parent field unless recursive processing yields no results
Subscripts (applies to array processing only):
  • true: Individual elements are reported
  • false (default): Only unique elements are reported with a subscript of *
Note: subscripts is a boolean value in the config object. The string shortcut 'subscripts' sets it to true.

Duration Operators

Duration operators work with duration strings and convert between different time units.
Available in SDK 4.12 onwards.

Collection Operators

The following table provides the collection operators for comparing if a given value is equal to any of the values in a list:

Array and Object Literals

Since version 4.8 of the Ditto SDK, Array and object literals are supported and can be used inline.
SQL
If using a version prior to 4.8, use arguments to pass in your array or object instead.
SQL

Array and Object Transformation Expressions

ARRAY and OBJECT transformation expressions are available in SDK v5+.
DQL provides powerful transformation expressions that allow you to create new arrays and objects by iterating over source collections and applying transformations, filters, and mappings.

ARRAY Transformation

The ARRAY transformation expression creates a new array by evaluating an expression for each element in a source array or object. Syntax:
DQL
Array Transform Syntax Diagram Components:
  • value_expr - Expression evaluated for each element (result added to output array unless MISSING)
  • name_var - Optional identifier holding the array index (for arrays) or field name (for objects)
  • value_var - Identifier holding the element value
  • source - Expression evaluating to an ARRAY or OBJECT
    • Returns MISSING if source is MISSING
    • Returns NULL if source is any other non-array/object type
  • condition - Optional filter; element included only if condition evaluates to true
  • IN - Process immediate content only
  • WITHIN - Recursively process nested arrays/objects
Examples:
DQL

OBJECT Transformation

The OBJECT transformation expression creates a new object by evaluating name and value expressions for each element in a source array or object. Syntax:
DQL
Object Transform Syntax Diagram Components:
  • name_expr - Expression for field name (must evaluate to string)
  • value_expr - Expression for field value (field added only if not MISSING)
  • name_var - Optional identifier holding the array index or field name
  • value_var - Identifier holding the element value
  • source - Expression evaluating to an ARRAY or OBJECT
    • Returns MISSING if source is MISSING
    • Returns NULL if source is any other non-array/object type
  • condition - Optional filter; element included only if condition evaluates to true
  • IN - Process immediate content only
  • WITHIN - Recursively process nested objects
Duplicate Names: When multiple elements produce the same field name, later values overwrite earlier ones without warning. This applies to both IN and WITHIN processing.
Examples:
DQL

Use Cases

Data Transformation:
DQL
Filtering and Mapping:
DQL
Restructuring Data:
DQL
Nested Processing:
DQL

Array and Object Search Expressions

DQL provides search expressions that test whether elements in arrays or objects satisfy specified conditions. These are particularly useful in WHERE clauses to filter documents based on nested data.

Syntax

DQL
Array Object Search Syntax Diagram Components:
  • name_var - Optional identifier holding the array index (for arrays) or field name (for objects)
  • value_var - Identifier holding the element value
  • expression - Expression evaluating to an ARRAY or OBJECT
    • Returns MISSING if expression evaluates to MISSING
    • Returns NULL if expression evaluates to any other non-array/object type
  • condition - Boolean expression tested against each element
  • IN - Search immediate content only
  • WITHIN - Recursively search nested arrays/objects
Search Operators:
  • ANY - Returns true if at least one element satisfies the condition (short-circuits on first match)
  • EVERY - Returns true if all elements satisfy the condition (empty arrays/objects return true)
  • ANY AND EVERY - Like EVERY but returns false for empty arrays/objects

Examples

Using ANY:
DQL
Using EVERY:
DQL
Using ANY AND EVERY:
DQL

IN vs WITHIN

The difference between IN and WITHIN is crucial: IN - Direct Search:
DQL
WITHIN - Recursive Search:
DQL
WITHIN with IS MISSING: Be careful when using WITHIN with IS MISSING predicates:
DQL
Use IN instead of WITHIN when checking for missing fields to avoid unexpected recursion.

Common Patterns

Filtering by Array Contents:
DQL
Validating All Elements:
DQL
Non-Empty Array with All Valid:
DQL
Searching Nested Structures:
DQL

Comparison Operators

The comparison operators fall into one of two sub-categories:
  • Missing value comparisons
  • Regular value comparisons
DQL has two ways of representing missing information in an object:
  • The presence of the field with a NULL for its value (as in SQL)
  • The absence of the field (which JSON permits)
The following table provides operators for comparing if a given value is equal to any of the values in a list: NULL and UNKNOWN are synonym keywords and provide the same behavior. If a field doesn’t exist in a document, any predicate using that field evaluates to MISSING (which is treated as false in WHERE clauses), except when using the IS MISSING or IS NOT MISSING operators which explicitly check for field existence.

Comparison Operations with NULL

In DQL, NULL represents missing or unknown data. It’s not a value in the way that 1 or 'text' are values. Any comparison operation that includes NULL will result in NULL.

Conditional Operators

Conditional Operators allow you to express conditional logic and handle NULL/MISSING values within your DQL queries.

CASE Expressions

CASE expressions provide conditional logic similar to if-then-else constructs. DQL supports both simple and searched CASE expressions.

Simple CASE

Compares an expression against multiple values:
DQL
Simple CASE Syntax Diagram When the result of expression matches a value, the corresponding result is returned. If there is no match and there is no ELSE clause, the result is NULL. The first branch with a matching value is used. Example:
DQL

Searched CASE

Evaluates multiple conditions:
DQL
Searched CASE Syntax Diagram When a condition evaluates to true, the corresponding result is returned. If there is no match and there is no ELSE clause, the result is NULL. The first branch with a true condition is used. Example:
DQL

Logical Operators

Logical operators perform logical NOTAND, and OR operations over Boolean values (TRUE and FALSE), plus NULL and MISSING.

NOT Truth Table

AND Truth Table

OR Truth Table

Aggregate Functions

DQL provides aggregate functions that operate on groups of documents to produce summary values. For complete documentation on using aggregates with GROUP BY, see SELECT - Aggregate Functions.
When DISTINCT is specified, only distinct values are considered in the calculations. This requires maintaining a record of all distinct values encountered, which increases memory requirements for large result sets.
Aggregate functions form a “dam” in the execution pipeline - all documents must be processed before results can be returned. This is different from non-aggregate queries which can stream results.

Miscellaneous Functions