query
The query task extracts data from an object or array variable and passes the result to a later task.
Use cases
Use the query task to do the following:
- Extract a value from a variable for evaluation or other downstream logic.
- Filter and manipulate data with the query syntax, such as returning only the array elements that match a condition.
To retrieve a value without adding a task to the canvas, apply a task input query to the input field instead. Use the query task when the result needs to be an output variable in its own right, such as when more than one later task reads the same reshaped data.
To query the output of a Gateway service, use the result.stdout_json property of the runService task output. This property contains the service’s standard output parsed as JSON.
To confirm the finish state of child job loops, use the loop[*].status query syntax to extract the resulting status of each child job run in the childJob task output.
Properties
Using the pass on null variable
The pass_on_null property determines the return_data value and the transition that the task takes when the query doesn’t match the object:
In the last scenario, pass_on_null has no effect. The task returns null and takes the success transition even when pass_on_null is false. Check for a null result before a later task uses it.
Task input queries handle failures differently so that missing or invalid data is caught as early as possible in the workflow. A task input query doesn’t use pass_on_null. If a task input query can’t find a key or index, the task takes its error transition, and the error message identifies the query. If a task input query finds a key whose value is null, the query succeeds and passes null to the input. For more information, see Task input query.
Query syntax
The examples in this section query the following object, which contains device data from a site:
The following table lists the supported query syntax. A query can start with or without a period. For example, site.name and .site.name return the same value.
For how these queries differ from Platform 6.4.0 task input queries, see Query syntax across Platform versions.
Helper functions
A helper function transforms or filters a value from a job or task variable or that the preceding part of the query returns.
To call a helper function on a value that an earlier part of the query returns, add a period before the function. For example, config.:getLiteral(ietf-system:system) calls :getLiteral() on the value of config. Use dot notation for every part of the path except a key that contains a special character. Use :getLiteral() only for that key.
A helper function can also start a query. It then reads from the top level of the object. For example, in the object { "ietf-system:system": { "contact": "neteng" } }, the query :getLiteral(ietf-system:system).contact returns "neteng".
Query a key that contains special characters
The query syntax assigns a meaning to some characters. Because the query library reads these characters as part of the query, dot notation can’t access a property whose key contains one. For example, the query region?id treats ? as query syntax and returns undefined. A hyphen (-) and an underscore (_) have no meaning in the query syntax, so use dot notation for a key that contains either one.
The following table lists the characters and what the query syntax uses them for:
Use dot notation wherever possible. To access a key that contains a special character, use :getLiteral(). It accesses a key that contains any of the characters in the previous table. It reads its argument as plain text, so a ? or . in the key is always part of the key, and you don’t enclose the key in quotation marks. Only ) and \ need an escape character. For more information, see Escape characters in the key.
:getLiteral() works at the start of a query and after a path. In the following examples, region?id is at the top level of the object, and mgmt:vlan is in the site object.
The examples in this section query the following object:
The :get() helper function is supported for backward compatibility, but use it with caution. It accesses a key that contains any special character except ?, ,, (, ), [, ], {, and }. For example, it accesses keys that contain ., :, or |. :getLiteral() accesses every key that :get() does, so use :getLiteral() instead.
Don’t use bracket notation, such as ["device_name"], to access a key. In the query task and in task input queries, use dot notation to access device_name. To access a key that contains a special character, use :getLiteral().
Escape characters in the key
:getLiteral() reads the key up to the first ) that you don’t escape. To include a ) or a backslash (\) in the key, escape the character with a backslash:
You don’t need to escape any other character, but every backslash must be part of \\ or \).
The examples in this section query the following object. The key Gi0/1 (uplink) contains a ). The key CORP\netadmin contains a backslash. JSON requires every backslash in a string to be escaped, so the object writes this key as "CORP\\netadmin".
The query package shares the same escape rule as JSON for backslashes, so enter each backslash in the key as \\ to match the JSON. For example, the key CORP\netadmin becomes :getLiteral(CORP\\netadmin). This matches the JSON spelling, so no edits are needed to the key. If a JSON viewer shows the key as CORP\\netadmin, don’t double the backslashes again: CORP\\\netadmin looks for a key with two backslashes.
Invalid :getLiteral() calls
A :getLiteral() call is invalid in any of the following cases. These calls are invalid regardless of what the object contains.
An invalid call returns undefined, so the query finds no value. Platform also skips everything after the invalid call, up to the next | or the end of the query. For example, in :getLiteral(a\b).c, Platform skips .c. In :getLiteral(a\b).c|d, Platform skips .c and returns the value of the d key.
Because the query finds no value, the result depends on pass_on_null. For more information, see Using the pass on null variable.
Remove duplicate values
:unique() returns each value in an array only once.
The following example uses an object in which each device is an element of the devices array. The query plucks the role value from every element and removes the duplicates.
Result:
:unique() works on arrays only, not objects.
Return entries that have a property
:exists() returns only the entries of an array or object that have the specified property.
The following example uses an object in which each device is an entry in a keyed object. The query returns the devices that have an owner property.
Result:
:exists() evaluates the entries of the value that precedes it. If that part of the query doesn’t return a value, :exists() returns {}.
Query syntax across Platform versions
In Platform 6.7.0 and later, the query task and task input queries use the same query syntax. The following list describes what’s shared and what isn’t:
- Shared syntax: Task input queries support the full syntax on this page, including filters, helper functions, and
:getLiteral(). Before Platform 6.7.0, task input queries supported data retrieval from objects and arrays only. - Separate failure handling: The query task uses
pass_on_nullwhen a query doesn’t match. A task input query takes the task’s error transition instead. For more information, see Using the pass on null variable. - Query task syntax: The query task syntax didn’t change in Platform 6.7.0 except for the addition of
:getLiteral(). Query tasks return the same values as before.