Downloads

AQL Query Syntax

Ataccama Query Language (AQL) is the filter language for entity listings in Ataccama ONE. An AQL filter is a condition on the properties of an entity, such as name like 'customer', and the listing shows only the entities that match it. This page describes the AQL syntax and provides example filters for catalog items, sources, attributes, terms, and rules.

When to use AQL

Full-text search finds entities by the words you type, matched against their names and other text. An AQL filter can use any property in the metadata model, including properties of related entities. For example, you can find catalog items from a given connection, with the term Email assigned to one of their attributes, with data quality under 80%, or changed in the last 24 hours. Use AQL when a search term can’t express the condition you need.

You can use AQL filters in the following places:

Good to know

Before you write a filter, keep the following in mind:

  • Write the filter for the entity you are listing: Each entity (such as a catalog item, source, or term) has its own properties, so a filter written for sources doesn’t work on catalog items. The examples on this page state which entity they are for.

  • Take property names from the metadata model: To see the properties of an entity, go to Global Settings > Metadata Model and open the entity. Property names are case-sensitive and written in camel case, for example, originPath.

    Avoid underscores (_) in the names of custom properties: they cause parsing problems in filters typed into the search bar and in page layouts.

  • Type only the condition: A filter consists of the condition alone, for example, name like 'customer'. Don’t wrap it in a GraphQL query. That format is used only when you call the GraphQL API, see Use AQL in the GraphQL API.

  • Quote string values: Enclose string values in single (') or double (") quotes.

  • Write keywords in any case: Keywords and operators are case-insensitive, so name LIKE 'x' and name like 'x' are the same.

Example filters

The following filters are ready to use on the listing named in each heading. Replace the values with your own.

Catalog items

To find Use

Catalog items whose name contains customer

name like 'customer'

Catalog items whose description contains the word customer

description fulltext 'customer'

Catalog items from the schema public

schema = 'public' or $parent.originPath = 'public'

Catalog items from the connection Snowflake prod

connection.name = 'Snowflake prod'

Views only

tableType = 'VIEW'

Catalog items that are delimited (CSV) or Parquet files

$type in ('delimitedFileCatalogItem', 'parquetFileCatalogItem')

Catalog items with a primary key

primaryKey is not null

Catalog items with the term Email assigned to the item itself

termInstances.any(target.name = 'Email')

Catalog items with an attribute that has the term Email assigned

attributes.any(termInstances.any(target.name = 'Email'))

Catalog items with at least one attribute without a term

attributes.any(termInstances.count() = 0)

Catalog items with an attribute named email

attributes.any(name = 'email')

Catalog items with overall data quality under 80%

validityAggr.overallQuality < 80

Catalog items without data quality results

validityAggr.overallQuality is null

Catalog items with more than one million records

numberOfRecords > 1000000

Catalog items with a profiling run that counted more than one million records

profilingConfigurationInstances.any(profiles.any(totalNumOfRecords > 1000000))

Catalog items that have never been profiled

numberOfRecords is null

Catalog items changed in ONE in the last 24 hours

$timestamp > 'now - 24 hours'

numberOfRecords holds the record count from the latest profiling. The filter on profiles also matches catalog items that had more than one million records in any earlier profiling run.

Sources

To find Use

Sources whose name contains postgres

name like 'postgres'

Sources named exactly mysql aws or postgres local

name in ('mysql aws', 'postgres local')

Sources with a description

description is not null

Sources with more than one connection

connections.count() > 1

Sources with a connection to a host whose name contains prod

connections.any(hostname like 'prod')

Sources with a connection that has more than one credential

connections.any(credentials.count() > 1)

Attributes

To find Use

STRING attributes of catalog items whose name contains customer

dataType = 'STRING' and $parent.name like 'customer'

Attributes with the term Email assigned

termInstances.any(target.name = 'Email')

Attributes without any term

termInstances.count() = 0

Terms

To find Use

Terms assigned to at least one catalog item or attribute

@termInstance(target).any()

Terms that aren’t assigned anywhere

@termInstance(target).count() = 0

Terms with at least one validation rule

validationRules.ruleInstances.count() > 0

Rules

To find Use

Rules with the data quality dimension Timeliness

implementation.dqDimension.name = 'Timeliness'

Rules used in at least one rule instance

@ruleInstance(target).any()

Combining conditions

Combine conditions with logical operators:

  • not (or !): The condition must not be satisfied.

  • and (or &, &&): Both conditions must be satisfied.

  • or (or |, ||): At least one condition must be satisfied.

Operators are evaluated in this order: not first, then and, then or. Use parentheses to change the order.

For example, the following conditions differ only in their parentheses:

  1. a is 1 and not b is 2 or c is 3

  2. (a is 1) and not (b is 2 or c is 3)

  3. a is 1 and (not (b is 2) or (c is 3))

Applied to the following data, they return different results:

  • a = 0, b = 0, c = 0: Matched by none.

  • a = 0, b = 2, c = 3: Matched by 1.

  • a = 1, b = 2, c = 3: Matched by 1 and 3.

  • a = 1, b = 0, c = 0: Matched by 1, 2, and 3.

Examples on sources:

  • name like 'mysql' and connections.count() > 1

  • name like 'mysql' or name like 'postgres'

Null values

A property is null when it has no value at all. This is different from an empty string (""), zero (0), or false.

You can test scalar properties, single embedded properties, and references for null values:

  • description is null (any entity)

  • description is not null

  • connection is not null (on catalog items, reference)

  • primaryKey is not null (on catalog items, single embedded)

Computed properties such as validityAggr on catalog items are always present, so testing them for null matches nothing. Test one of their values instead, for example, validityAggr.overallQuality is null.

Array properties can’t be tested for null. To find entities with an empty array, use count() = 0, for example, connections.count() = 0 on sources. See Array properties.

Scalar conditions

Scalar conditions compare the value of a property with a constant.

The constant is always on the right side of the condition. You can’t compare two properties with each other.

Values

A constant can be one of the following types:

  • Boolean: true or false (case-insensitive).

  • Number: Any JSON5-compatible number.

    • Decimal integers: 0, 42, -175.

    • Decimal real numbers: 5.05, -17.666, 15., .5.

    • Decimal real numbers with an exponent: 15.5e3, 5e-2.

    • Hexadecimal integers: 0x0, 0XBA0BAB, 0xc0c0a.

    • Positive and negative Infinity, NaN (case-sensitive).

  • String: Any JSON5-compatible string.

    • Single-quoted: 'cat', 'single'quote', 'with new\nline'.

    • Double-quoted: "dog", "double\"quote", "with\ttab".

The syntax accepts any number. Whether the number fits the property is checked when the filter runs.

Comparison operators

Compare a property with a constant using the following operators:

  • Equal: = (or is, eq, ==).

  • Not equal: != (or is not, ne, neq, <>).

  • Less than: < (or lt).

  • Greater than: > (or gt).

  • Less than or equal: <= (or le, lte).

  • Greater than or equal: >= (or ge, gte).

  • Contains substring: like (or match, ~).

  • Contains word: fulltext.

Not all operators work with all data types:

  • Equal and not equal work with all types.

  • Less than, greater than, and their variants work with numeric types (INTEGER, LONG, FLOAT, DOUBLE).

  • like and fulltext work with strings.

The like operator matches a substring anywhere in the value and is case-insensitive. The characters % and _ are matched literally, not as wildcards, and there is no operator for "starts with".

An exception is the catalog item filter in the connection browser, where % and _ work as wildcards. See Supported AQL syntax.

The fulltext operator matches whole words and is case-insensitive. Words are separated by spaces, punctuation, and underscores, so name fulltext 'customer' matches CUSTOMER_SOURCE and Customer Profitability but not customers.

When the filter contains several words, a value matches only if it contains all of them. To match any of the words, separate them with or; to match a phrase, enclose it in double quotes; to exclude a word, prefix it with -. For example, description fulltext 'customer -data' matches descriptions that contain the word customer but not the word data.

Examples on sources:

  • name == 'mysql aws'

  • name like 'mysql'

  • connections.count() >= 2

  • $fulltext like 'party'

Lists of values

To check whether a value is or isn’t in a list, use in or not in. All values in the list must be of the same type.

Examples:

  • name in ('mysql aws', 'postgres local') (on sources)

  • dataType not in ('STRING', 'INTEGER') (on attributes)

Several conditions on one property

You can combine several conditions on the same property without repeating its name. The property applies to all conditions:

  • numberOfRecords > 1000 and < 10000 is the same as numberOfRecords > 1000 and numberOfRecords < 10000.

  • name (like 'customer' or like 'client') and not like 'test' is the same as (name like 'customer' or name like 'client') and not name like 'test'.

Conditions combined in this way can’t include a null test. Use this shorthand sparingly, as it can be hard to read.

Single embedded properties, references, and the parent entity

You can place a condition on a single embedded property, a single reference, or the parent entity, and combine it with other conditions.

Full syntax:

  • singleEmbeddedProperty { condition }

  • referenceProperty { condition }

  • $parent { condition }

The condition in the braces can be any condition described on this page, applied to the related entity.

If the nested condition is a single simple condition, use the shorthand syntax:

  • singleEmbeddedProperty.property = 'x'

  • referenceProperty.property = 'x'

  • $parent.property = 'x'

Both syntaxes can be chained: connection { name like 'prod' } and $parent.originPath = 'public'. If the related entity is missing, the condition is false. Single embedded properties and references can be tested for null; the parent entity can’t.

Examples:

  • connection.name = 'Snowflake prod' (on catalog items)

  • $parent.originPath = 'public' (on catalog items; the parent is the schema or folder the item is in)

  • $parent { name like 'customer' and schema = 'public' } and dataType = 'STRING' (on attributes; the parent is the catalog item)

Array properties

You can place a condition on array embedded properties, array references, and back references. The condition is evaluated for every element of the array, and an aggregation decides whether the entity matches.

Two syntaxes are available:

  • arrayProperty.aggregation(condition): A single aggregation.

  • arrayProperty { aggregation(condition) and aggregation(condition) }: Several aggregations on the same array combined with logical operators.

The following aggregations are available:

  • all(condition): All elements must match. The condition is required.

  • none(condition): No element can match. The condition is required.

  • any(condition) or some(condition): At least one element must match. The condition is optional; without it, the array must not be empty.

  • count(condition) scalarCondition: The number of matching elements is compared using a scalar condition. Without a condition, all elements are counted.

If the array is empty, all and none are true and count() is 0. Array properties can’t be tested for null.

Examples:

  • attributes.any(dataType = 'STRING') (on catalog items)

  • attributes.all(termInstances.count() > 0) (on catalog items; every attribute has a term)

  • attributes.count(dataType = 'STRING') = 1 (on catalog items)

  • attributes { any(dataType = 'STRING') and count() > 10 } (on catalog items)

  • connections.none(hostname like 'test') (on sources)

  • connections.any(credentials.count() > 1) (on sources)

Back references

A back reference finds entities that are referenced by other entities. It uses the same aggregations as array properties.

The syntax names the referencing entity and the referencing property. Both are optional, but we recommend always specifying both to avoid unexpected results:

  • @referencingEntity(referencingProperty).aggregation(condition): The referencingProperty of referencingEntity points to the current entity.

  • @referencingEntity().aggregation(condition): Any reference in referencingEntity points to the current entity.

  • @(referencingProperty).aggregation(condition): The referencingProperty of any entity points to the current entity.

  • @().aggregation(condition): Any reference of any entity points to the current entity.

The condition applies to the referencing entity.

Examples on terms, where term instances reference the term through their target property:

  • @termInstance(target).any(): Terms assigned to at least one catalog item or attribute.

  • @termInstance(target).count() = 0: Terms that aren’t assigned anywhere.

  • @termInstance(target).count() > 5: Terms assigned more than five times.

  • @termInstance(target).any(exceptionCount > 0): Terms with at least one assignment that has exceptions.

Examples on rules, where rule instances reference the rule through their target property:

  • @ruleInstance(target).any(): Rules used in at least one rule instance.

System properties

System properties are available on every entity and start with a dollar sign ($):

  • $id: The identifier (GID) of the entity, as a string. For example, $id = '0e40b980-d671-4021-876f-a5dbb3d2052c'.

  • $fulltext: All string properties of the entity combined into one string. For example, $fulltext like 'party', or connections.any($fulltext like 'aws') on sources.

  • $path: The position of the entity type in the metadata model tree, for example, /sources/locations/catalogItems for catalog items. It is mainly useful when a listing mixes several entity types, for example, $path like 'catalogItems'.

  • $type: The entity type in the metadata model, for example, tableCatalogItem or businessTerm. Catalog items, attributes, and terms come in several types, so $type selects a subset of the listing, for example, $type in ('delimitedFileCatalogItem', 'parquetFileCatalogItem') for catalog items that are delimited or Parquet files.

    The type names are the entity names in Global Settings > Metadata Model; the base type catalogItem matches nothing on its own, as every catalog item has a specific type.

    Use in to match several types, as or and not don’t work with $type.

  • $draftType: The unpublished change on the entity: NEW, CHANGE, or DELETE, or UNCHANGED when there is none. It is evaluated on the version the query returns, so in the GraphQL API use it with versionSelector: { draftVersion: true }, for example, $draftType in ('NEW', 'CHANGE', 'DELETE') for entities with unpublished changes. In a listing, use the Unpublished tab instead.

  • $ancestorIds: The GIDs of all entities above the entity in the metadata hierarchy, as an array. It is available only in the GraphQL API because the search bar editor doesn’t accept the operators that compare arrays. See Use AQL in the GraphQL API.

  • $parent: The parent entity, see references, and the parent entity.

  • $timestamp: The time when the current version of the entity was created or last changed in ONE. For example, $timestamp > 'now - 2 days'. See Timestamp conditions.

Timestamp conditions

Use timestamp conditions on the $timestamp system property or on timestamp properties of an entity. For example, createdAt and modifiedAt on catalog items hold the timestamps from the data source, when the source provides them.

All comparison operators, in and not in, and null tests are supported. The value is always written as a string and can be absolute or relative.

Absolute values

An absolute value follows this generalized ISO 8601 pattern, in which every part is optional:

Absolute value pattern
(YYYY-MM-DD)?                  # Date
[T ]?                          # Separator between date and time
(hh:mm(:ss)?(.sss)?)?          # Time
(Z|[+-]h(h(:?mm(:?ss)?)?)?)?   # Time zone

The value is interpreted in the following order, depending on which parts are present:

  1. Date, time, and time zone: All parts are used as written.

  2. Date and time: The server time zone is applied.

  3. Time and time zone: The current date in the given time zone is used.

  4. Time: The current date in the server time zone is used.

  5. Date: The beginning of the day in the server time zone is used.

We recommend specifying all parts unless the filter is for one-time use.

Examples:

  • $timestamp < '2026-06-05T17:15:15+02:00': Changed before 17:15:15 on June 5, 2026, UTC+2.

  • $timestamp > '2026-01-01': Changed after midnight on January 1, 2026, server time zone.

  • $timestamp > '11:35Z': Changed after 11:35 UTC today.

Relative values

A relative value starts with now, the current timestamp. You can truncate it to the beginning of a unit and shift it by a number of units:

Relative value pattern
now (TZ)? (/ UNIT)? ([+-] AMOUNT UNITs?)?

The available units are second, minute, hour, day, week, month, and year. The unit can be plural.

Truncating with / UNIT moves the timestamp to the beginning of that unit, for example, midnight of the current day or the first day of the current month. Use it to find everything changed since midnight or since the start of the month, as opposed to everything changed in the last 24 hours or 30 days. Weeks start on Monday.

For the units day, week, month, and year, provide the time zone so that the beginning of the unit can be determined. The time zone format is the same as for absolute values. If you don’t provide it, the server time zone is used.

The shift is applied after the truncation.

Examples:

  • $timestamp > 'now - 24 hours': Changed in the last 24 hours.

  • $timestamp >= 'now / month': Changed since the start of the current month, server time zone.

  • $timestamp >= 'now +2 / day + 8 hours': Changed since 08:00 today, UTC+2.

  • $timestamp < 'now / year': Last changed before January 1 of the current year, server time zone.

Use AQL in the GraphQL API

In the GraphQL API, pass the same condition as the filter argument of a listing query:

Views that have at least one STRING attribute
query {
  catalogItems(
    filter: "tableType = 'VIEW' and attributes.any(dataType = 'STRING')"
    versionSelector: { publishedVersion: true }
  ) {
    totalCount
  }
}

The API also accepts conditions that the search bar editor doesn’t: $ancestors(entity), $descendants(entity), and the contains operators on the $ancestorIds system property.

$ancestors(entity) and $descendants(entity) place a condition on all entities of a given type that contain the current entity or that it contains, at any depth of the metadata hierarchy, using the same aggregations as array properties. With count, only a comparison with 0 is supported.

Examples for the filter argument
$ancestors(source).any(name = 'Snowflake')          # catalog items or attributes from the source Snowflake
$descendants(catalogItem).count() = 0                 # sources with no catalog items
$descendants(attribute).any(dataType = 'STRING')     # sources with a STRING attribute in any catalog item

$ancestorIds holds the GIDs of all entities above the current entity in the metadata hierarchy, as an array of strings. Compare it with a list of GIDs in square brackets using one of the following operators:

  • contains_all […​]: The array contains every listed GID.

  • contains_some […​]: The array contains at least one of the listed GIDs.

  • contains_none […​]: The array contains none of the listed GIDs.

With an empty list, contains_all and contains_none match every entity and contains_some matches none. AQL also defines contains_only, but it isn’t supported on $ancestorIds.

Examples for the filter argument
$ancestorIds contains_all ['15bbce34-0000-7000-0000-0000001602f5']                                          # catalog items or attributes from the source with this GID
$ancestorIds contains_some ['15bbce34-0000-7000-0000-0000001602f5', '15bbce34-0000-7000-0000-0000001612c9']  # from either of two sources
$ancestorIds contains_none ['15bbce34-0000-7000-0000-0000001602f5']                                         # from any other source

To learn more, see ONE API.

Was this page useful?