MQL Built-in Functions Reference
Complete reference for all MQL built-in functions
Built-in functions are the core language features that let you filter, transform, and make assertions across collections of data. They are the difference between just retrieving raw data and turning that data into meaningful answers.
Think of built-ins as the verbs of MQL:
.where()narrows down what you're looking at..map()transforms the results..all(),.any(),.none(),.one()let you assert truth over collections..having()filters like.where()and also asserts that something matched..lengthand.containsOnlyhelp you structure and compare results.
Overview
Array Functions
| Function | Summary |
|---|---|
| all | Assert all elements satisfy predicate |
| any | Assert at least one element satisfies predicate |
| contains | Check if array contains a value or matches predicate |
| containsAll | Check that array contains all specified values |
| containsNone | Check that array contains none of the specified values |
| containsOnly | Check that array contains only specified values |
| duplicates | Return duplicate values (optionally by field) |
| first | Return the first element of an array |
| flat | Flatten nested arrays |
| having | Filter by predicate and assert that something matched |
| in | Check that every string in an array is in a list |
| join | Join all values in an array into a single string |
| last | Return the last element of an array |
| length | Return the number of elements in the array |
| map | Transform each element |
| none | Assert no elements satisfy predicate |
| notIn | Check that an array has a string that isn't in a list |
| one | Assert exactly one element satisfies predicate |
| reverse | Reverse the order of the array |
| sample | Return a random sample of elements |
| unique | Return unique values |
| where | Filter by predicate |
Map Functions
| Function | Summary |
|---|---|
| all | Assert all entries satisfy predicate |
| contains | Check if any entry matches a value or predicate |
| having | Filter entries and assert that something matched |
| keys | Return the keys of the map |
| length | Number of entries in the map |
| none | Assert no entry satisfies predicate |
| one | Assert exactly one entry satisfies predicate |
| sample | Return a random sample of entries |
| values | Return the values of the map |
| where | Filter map entries by predicate |
String Functions
| Function | Summary |
|---|---|
| camelcase | Convert string to camelCase |
| contains | Check if string contains a substring or matches regex |
| downcase | Convert string to lowercase |
| find | Find all regex matches in the string |
| in | Check if string is in a list |
| inRange | Check if string represents a number within a range |
| json | Decode the string as JSON (experimental) |
| length | Number of bytes in the string |
| lines | Split string into lines |
| notIn | Check if string is not in a list |
| split | Split string by a delimiter |
| trim | Trim whitespace or specified characters |
| upcase | Convert string to uppercase |
Number Functions
| Function | Summary |
|---|---|
| inRange | Check if a number is within a range |
Time Functions
| Function | Summary |
|---|---|
| days | Convert a duration to whole days |
| hours | Convert a duration to whole hours |
| inRange | Check if time is within a range |
| minutes | Convert a duration to whole minutes |
| seconds | Convert a duration to seconds |
| unix | Convert to Unix epoch seconds |
IP / Network Functions
| Function | Summary |
|---|---|
| address | Return the IP address without its prefix |
| cidr | Return the address in CIDR notation |
| inRange | Check if IP is in a network or range |
| isPublic | Check if IP is publicly routable |
| isUnspecified | Check if IP is unspecified (0.0.0.0 or ::) |
| prefix | Return the network prefix |
| prefixLength | Return prefix length |
| subnet | Return the subnet mask or subnet ID |
| suffix | Return suffix (host bits) |
| version | Return IP version (4 or 6) |
Parse Functions
| Function | Summary |
|---|---|
| parse.date | Parse a date string into a time value |
| parse.duration | Parse a duration string into a duration value |
| parse.json | Parse JSON from a file or from content |
Regex Patterns
| Function | Summary |
|---|---|
| regex.creditCard | Match credit card numbers |
| regex.email | Match email addresses |
| regex.emoji | Match emojis |
| regex.ipv4 | Match IPv4 addresses |
| regex.ipv6 | Match IPv6 addresses |
| regex.mac | Match MAC addresses |
| regex.semver | Match semantic version numbers |
| regex.url | Match URL addresses (HTTP/HTTPS) |
| regex.uuid | Match UUIDs |
Version Functions
| Function | Summary |
|---|---|
| version | Parse a version string so it compares as versions |
| epoch | Return the epoch of a version |
| inRange | Check if a version satisfies two bounds |
Type Conversion Functions
| Function | Summary |
|---|---|
| bool | Convert a value to a boolean |
| dict | Convert a value to a dict |
| float | Convert a value to a float |
| int | Convert a value to an integer |
| ip | Convert a string or integer to an IP address |
| regex | Convert a string to a regular expression |
| string | Convert a value to a string |
| typeof | Return the name of a value's type |
Dict Functions
| Function | Summary |
|---|---|
| recurse | Traverse nested dict structures |
Array Functions
array.all
Assert that all elements in an array satisfy the condition. Empty arrays return true.
Ensure all EC2 instances do not have a public IP address:
aws.ec2.instances.all( publicIp == empty )Example output:
aws.ec2.instances.all( publicIp == empty )
[failed] [].all()
actual: [
0: aws.ec2.instance region="us-east-1" state="running" instanceType="t2.large" instanceId="i-0684b0bfd64641234" architecture="x86_64" platformDetails="Linux/UNIX" {
publicIp: "54.144.152.249"
}
]array.any
Assert that at least one element in an array satisfies the condition. Empty arrays return false.
Check if at least one SSH service is running:
services.any(name == "sshd" && running == true)Example output:
services.any(name == "sshd" && running == true)
[ok] value: truearray.contains
Check if an array contains a specific value or if any element matches a predicate. Returns true if found.
Check if any package is named openssl:
packages.map(name).contains("openssl")Example output:
packages.map(name).contains("openssl")
[failed] [].contains()
expected: > 0
actual: 0array.containsAll
Check that an array contains all specified values. Returns true only if all are present.
Ensure both root and ec2-user exist:
users.map(name).containsAll(["root","ec2-user"])Example output:
users.map(name).containsAll(["root","ec2-user"])
[failed] [].containsAll()
expected: == []
actual: [
0: "ec2-user"
]array.containsNone
Check that an array contains none of the specified values. Returns true if no matches are found.
Ensure no insecure packages are installed:
packages.map(name).containsNone(["telnet","rsh"])Example output:
packages.map(name).containsNone(["telnet","rsh"])
[failed] [].containsNone()
expected: == []
actual: [
0: "telnet"
]array.containsOnly
Check that all elements in an array are from an allowlist. Returns true if no other values appear.
Ensure only root and shadow groups own /etc/gshadow:
["/etc/gshadow"].where(file(_).exists) {
file(_) {
group.name.lines.containsOnly(["root","shadow"])
}
}Example output:
where: [
0: {
file: {
[].containsOnly(): true
}
}
]array.duplicates
Return the values that appear more than once in an array. On an array of resources or maps, pass a field to compare entries by that field and return every entry that shares its value with another.
Find duplicate package names:
packages.map(name).duplicatesFind users that share a UID:
users.list.duplicates(uid)array.first
Return the first element of an array.
Get the first package installed on the system:
packages.map(name).firstarray.flat
Flatten nested arrays into a single array.
Flatten a deeply nested array:
[[[1,2,3]]].flatarray.having
Filter an array by a condition, like where, and also assert that at least one element matched. Chain an assertion after it to avoid the empty list trap: where(...).all(...) passes when nothing matches, while having(...).all(...) fails.
Assert that at least one number is greater than 1, and that all of those are less than 5:
[1, 2, 3].having( _ > 1 ).all( _ < 5 )Example output:
[ok] [1, 2, 3].having( _ > 1 ).all( _ < 5 )
[ok] value: true
[ok] value: trueIf nothing matches, the check fails even though all has nothing to object to:
[failed] [1,2,3].having(_ > 5).all(_ < 5)
[failed] [].having()
actual: []
[ok] value: truearray.in
Check that every string in an array is also in another list. To check a single string, use string.in.
Check that all configured SSH ciphers are on an allowlist:
sshd.config.ciphers.in(["aes256-gcm@openssh.com", "chacha20-poly1305@openssh.com"])Example output:
[failed] sshd.config.ciphers.in
expected: == true
actual: falsearray.join
Join all values in an array into a single string. By default, values are joined with no separator. Pass a string to use it as the separator.
Join the values ["a", "b", "c"] into "abc":
["a", "b", "c"].joinExample output:
join: "abc"Join the values with a comma:
["a", "b", "c"].join(",")Example output:
join: "a,b,c"array.last
Return the last element of an array.
Get the last installed package:
packages.map(name).lastarray.length
Return the number of elements in an array.
Count the number of installed packages:
packages.lengtharray.map
Transform each element of an array. Returns a new array with the transformed values.
List all package names:
packages.map(name)array.none
Assert that no elements in an array satisfy the condition.
Ensure no X11-related packages are installed:
packages.none(name == /^x(org|server|11)/i)array.notIn
The inverse of array.in: return true if at least one string in the array is not in the list. To check a single string, use string.notIn.
["a", "q"].notIn(["a", "b", "c"])Example output:
[ok] value: truearray.one
Assert that exactly one element in an array satisfies the condition.
Ensure exactly one default route exists:
network.routes.one(destination == "0.0.0.0/0")array.reverse
Reverse the order of elements in an array.
Reverse the order of values in an array:
[1, 2, 3].reverseExample output:
reverse: [
0: 3
1: 2
2: 1
]Reverse the order of period separated values using split, reverse, and join:
"123.456.789.10".split(".").reverse.join(".")Example output:
split.reverse.join: "10.789.456.123"array.sample
Return a random sample of elements from an array. The argument sets how many elements to return.
Return two random packages:
packages.sample(2)Example output:
packages.sample: [
0: deb://e2fsprogs/1.47.0-2.4~exp1ubuntu4.1/arm64
1: deb://libpam0g/1.5.3-5ubuntu5.7/arm64
]array.unique
Return only unique elements from an array. It takes no arguments and works on arrays of values that MQL can compare, such as strings and numbers.
List unique package names:
packages.map(name).uniquearray.where
Filter an array by a boolean condition. Returns a new array of elements that satisfy the predicate.
List all packages that start with "openssl":
packages.where(name == /^openssl/)Map Functions
map.all
Assert that all entries in the map satisfy a condition. Empty maps return true.
All net.* kernel parameters are non-zero:
kernel.parameters.where(key == /^net\./).all(value != 0)map.contains
Check whether any entry in the map satisfies a condition. Returns true if at least one match is found.
At least one kernel parameter vm.swappiness is set to 60 or less:
kernel.parameters.contains(key == "vm.swappiness" && value <= 60)map.having
Filter map entries by a condition, like where, and also assert that at least one entry matched. See array.having for why this matters when you chain an assertion.
At least one entry has a value above 1, and all of those are below 5:
{"a": 1, "b": 2}.having( value > 1 ).all( value < 5 )map.keys
Return the keys of a map as an array.
List kernel parameter names:
kernel.parameters.keysmap.length
Return the number of entries in a map.
Count the kernel parameters:
kernel.parameters.lengthmap.none
Assert that no entries in the map satisfy a condition.
No kernel parameter named net.ipv4.ip_forward is set to 1:
kernel.parameters.where(key == "net.ipv4.ip_forward").none(value == 1)map.one
Assert that exactly one entry in the map satisfies a condition.
Exactly one label sets the environment to prod:
asset.labels.one(key == "env" && value == "prod")map.sample
Return a random sample of entries from a map. When a number is provided, returns that many entries.
Return a single random kernel parameter:
kernel.parameters.sample(1)map.values
Return the values of a map as an array.
List kernel parameter values:
kernel.parameters.valuesmap.where
Filter map entries by a boolean condition. Returns a new map with only the matching key/value pairs.
Kernel parameters with names starting with net.:
kernel.parameters.where(key == /^net\./)String Functions
string.camelcase
Convert a string to camelCase.
Convert a phrase to camelCase:
"hello world".camelcasestring.contains
Check if a string contains a substring or matches a regex. Returns true if found.
Check if /etc/passwd contains root:
file("/etc/passwd").content.contains("root")string.downcase
Convert a string to lowercase.
Convert a username to lowercase:
"ROOT".downcasestring.find
Find all regex matches in a string. Returns an array of matches.
Find all numeric substrings:
"error codes: 123 456 789".find(/[0-9]+/)string.in
Check if the string is contained in a list. Returns true if found.
Check if prod is in the list of environments:
"prod".in(["dev","test","prod"])string.inRange
Check if the string (when interpreted as a number) falls within a range. Returns true if within bounds.
Check if "42" is between 10 and 100:
"42".inRange(10, 100)string.json
Experimental. Decode the string as a JSON document and return it as a dict you can traverse. This is useful for command output and other strings that hold JSON.
Read a field from the JSON output of a command:
command("lsblk --json").stdout.json.blockdevicesIf the string isn't valid JSON, the result is an error that names the parse failure.
string.length
Return the length of a string in bytes. A multibyte UTF-8 character counts as more than one byte, so "héllo".length is 6.
Get the length of a package name:
"openssl".lengthstring.lines
Split a string into an array of lines.
Split /etc/passwd into lines:
file("/etc/passwd").content.linesstring.notIn
Check if the string is not contained in a list. Returns true if not found.
Check if qa is not in the list of environments:
"qa".notIn(["dev","test","prod"])string.split
Split a string by a delimiter. Returns an array.
Split a comma-separated string:
"dev,test,prod".split(",")string.trim
Trim whitespace (or optionally specified characters) from the beginning and end of a string.
Trim spaces from a string:
" hello ".trimstring.upcase
Convert a string to uppercase.
Convert a username to uppercase:
"root".upcaseNumber Functions
number.inRange
Check if a number falls within a specified inclusive range. Returns true if within bounds.
Check if a number is between 10 and 100:
42.inRange(10, 100)Time Functions
MQL represents both points in time and durations with the time type. Subtracting one time from another, such as time.now - parse.date("2025-01-01"), produces a duration. The days, hours, minutes, and seconds functions convert a duration into a whole number of that unit, rounding down. They're meant for durations; on a point in time such as time.now, they return a large number that has no practical meaning.
The time resource also provides unit constants for building durations: time.second, time.minute, time.hour, and time.day. For example, 2 * time.hour is a two hour duration.
time.days
Convert a duration into whole days.
Count the days since a date:
(time.now - parse.date("2025-01-01")).daysConvert a parsed duration into days:
parse.duration("36h").daysExample output:
parse.parse.duration.days: 1time.hours
Convert a duration into whole hours.
Convert a parsed duration into hours:
parse.duration("90m").hoursExample output:
parse.parse.duration.hours: 1time.inRange
Check whether a time falls between two other times (inclusive).
Check if the current time is in a maintenance window:
time.now.inRange(
parse.date("2025-05-01 00:00", "2006-01-02 15:04"),
parse.date("2025-05-01 06:00", "2006-01-02 15:04")
)Check that no AWS Certificate Manager certificate expires within the next 30 days:
aws.acm.certificates.none( notAfter.inRange(time.now, time.now + parse.duration("30d")) )time.minutes
Convert a duration into whole minutes.
Convert a parsed duration into minutes:
parse.duration("2h").minutestime.seconds
Convert a duration into seconds.
Convert the built-in one day duration into seconds:
time.day.secondstime.unix
Convert a time into Unix epoch seconds.
Get the current Unix epoch:
time.now.unixConvert a parsed date into Unix epoch:
parse.date("2025-01-01", "2006-01-02").unixIP / Network Functions
Create an IP value with ip(), which accepts an IPv4 or IPv6 address as a string, optionally with a prefix length ("10.0.0.1/16"), or an IPv4 address as an integer. An IPv4 address without a prefix length uses its classful default (/8 for 10.0.0.1, /16 for 172.16.0.1, /24 for 192.168.0.1), and an IPv6 address without one uses /64.
ip.address
Return the IP address as a string, without its prefix length. To get the network address, use ip.prefix.
ip("192.168.1.10/24").addressExample output:
ip.address: "192.168.1.10"IPv6 example:
ip("2001:db8:abcd:1::123/64").addressip.cidr
Return the address and its prefix length in CIDR notation. If you didn't give a prefix length, the default one is used.
ip("10.0.5.7/16").cidrExample output:
ip.cidr: "10.0.5.7/16"Without a prefix length, ip("10.0.5.7").cidr returns "10.0.5.7/8".
ip.inRange
Check whether an IP is in a network or within a range of addresses.
With one argument, inRange returns true when the IP and the network have the same network prefix. Each side uses its own prefix length, so give the IP the same prefix length as the network you compare it to.
IPv4 address in a network:
ip("10.0.5.7/16").inRange("10.0.0.0/16")IPv6 address in a network:
ip("2001:db8::123/48").inRange("2001:db8::/48")With two arguments, inRange returns true when the IP is between the two addresses, inclusive:
ip("10.0.0.5").inRange("10.0.0.1", "10.0.0.10")ip.isPublic
Return true if the IP is publicly routable. An IP is not public if it's a loopback, private (RFC 1918 or RFC 4193), link-local, multicast, or unspecified address.
ip("8.8.8.8").isPublicPrivate addresses return false:
ip("10.1.1.1").isPublicip.isUnspecified
Return true if the IP is unspecified (0.0.0.0 for IPv4 or :: for IPv6).
Unspecified IPv4:
ip("0.0.0.0/0").isUnspecifiedUnspecified IPv6:
ip("::/0").isUnspecifiedip.prefix
Return the network prefix (network portion) of the IP.
IPv4 example:
ip("192.168.0.1").prefixAnother IPv4 example:
ip("10.0.5.123").prefixip.prefixLength
Return the prefix length of a CIDR.
Prefix length for IPv4:
ip("192.168.1.10/24").prefixLengthPrefix length for IPv6:
ip("2001:db8::1/56").prefixLengthip.subnet
For IPv4, return the subnet mask. For IPv6, return the subnet ID: the bits between the prefix and the 64 bit interface identifier. An IPv6 address with a prefix length of 64 or more has no subnet ID and returns an empty string.
IPv4 example:
ip("192.168.0.1/24").subnetExample output:
ip.subnet: "255.255.255.0"IPv6 example:
ip("2001:db8:abcd:12::1/48").subnetExample output:
ip.subnet: "12"ip.suffix
Return the host suffix (host bits) of the IP within its network.
IPv4 example:
ip("192.168.0.1").suffixip.version
Return the IP version (4 or 6).
IPv4 example:
ip("192.168.1.10/24").versionParse Functions
parse.date
Parse a date string into a time value. Without a second argument, MQL tries these layouts in order until one matches: RFC 3339, 2006-01-02 15:04:05, 2006-01-02, 15:04:05, RFC 1123, RFC 1123 with a numeric zone, ANSI C, RFC 822, RFC 822 with a numeric zone, RFC 850, kitchen (3:04PM), and stamp (Jan _2 15:04:05).
To use a specific layout, pass it as the second argument. It can be a named layout (rfc3339, rfc1123, rfc1123z, rfc822, rfc822z, rfc850, ansic, kitchen, stamp, datetime, date, or time) or a Go layout string. MQL lowercases the layout before it uses it, so a Go layout that spells out month or day names, such as Jan or Mon, doesn't match. Use a named layout for those formats.
Parse a date using the default RFC 3339 format:
parse.date("2025-10-12T14:42:35Z")Parse a date with a custom layout:
parse.date("2025-01-01", "2006-01-02")Parse a date with date and time layout:
parse.date("2025-05-01 00:00", "2006-01-02 15:04")Parse a date with a named layout:
parse.date("Mon, 02 Jan 2006 15:04:05 MST", "rfc1123")parse.duration
Parse a duration string into a duration value. A duration is a whole number followed by one unit. Combined values such as 1h30m and fractions such as 1.5h aren't supported and return an error.
Parse a duration in days:
parse.duration("3days")Parse a duration in years:
parse.duration("1y")Supported units:
| Unit | Accepted spellings |
|---|---|
| Seconds | s, sec, second, seconds, or no unit |
| Minutes | m, min, minute, minutes |
| Hours | h, hour, hours |
| Days | d, day, days |
| Years | y, year, years (a year is 365 days) |
For example, 30s is 30 seconds, 3h is 3 hours, 90d is 90 days, and 5y is 5 years.
Use parsed durations in time arithmetic:
time.now + parse.duration("720h")parse.json
Parse JSON data from a file or from a string. The params field holds the decoded document as a dict that you can query with MQL.
The unnamed argument is always a file path. To parse a string, such as command output, pass it as the named content argument. You can also call string.json on the string.
Parse a JSON file:
parse.json("my.json")Parse JSON from command output:
parse.json(
content: command('lsblk --json').stdout
)Access keys and values from parsed JSON:
parse.json("my.json").params.keysparse.json("my.json").params["f"][0]The same pattern works for other formats. parse.yaml, parse.xml, parse.plist, and parse.ini read YAML, XML, property list, and INI files, and parse.certificates and parse.openpgp read certificate and key files. To learn more, read the os resource reference.
Regex Patterns
Built-in regular expression patterns for common formats. Use these with comparison operators to validate strings.
regex.creditCard
Match credit card numbers:
"4832500902091714" == regex.creditCardregex.email
Match email addresses:
"anya@forger.com" == regex.emailregex.emoji
Match emojis:
"hello 🌍".contains(regex.emoji)regex.ipv4
Match IPv4 addresses:
"10.0.0.255" == regex.ipv4regex.ipv6
Match IPv6 addresses:
"fe80::1042:2c47:b787:f6bb" == regex.ipv6regex.mac
Match MAC addresses:
"00:1A:2B:3C:4D:5E" == regex.macregex.semver
Match semantic version numbers:
"1.2.3" == regex.semverregex.url
Match URL addresses (HTTP/HTTPS):
"https://example.com/path" == regex.urlregex.uuid
Match UUIDs:
"550e8400-e29b-41d4-a716-446655440000" == regex.uuidVersion Functions
version
Parse a string as a version so that comparisons order it as a version rather than as text. MQL compares versions in this order:
- Epoch. A version with a higher epoch (
1:2.4.52or1!2.0) is newer, regardless of the rest. - Release. Everything before the first
-, compared component by component. Numbers compare as numbers, so1.10is newer than1.2, and missing trailing components count as zero, so1.2sorts the same as1.2.0. There's no limit on the number of components. - Suffix. Everything after the first
-. A prerelease word (alpha,beta,rc,pre,prerelease,preview,dev,devel,snapshot,nightly,canary, ormilestone) sorts before the release, so1.0.0-rc1is older than1.0.0. Anything else, such as a distribution revision, sorts after it, so1.2.3-1ubuntu1is newer than1.2.3.
A leading v doesn't affect the order, a ~ sorts before everything (Debian's prerelease marker), and +build metadata doesn't affect the order.
The ordering rules apply to <, <=, >, >=, and inRange. The == and != operators compare the version strings exactly, so version('1.2') == version('1.2.0') is false.
Create a version:
version('3.12.1')Compare two versions:
version('1.2.3') < version('2.3')Compare a version with a string:
version('1.10') >= '1.2'Distribution package versions compare the way their package managers order them:
version('1.2.3-r4') < version('1.2.3-r10')To require a specific format, pass type. MQL returns an error if the string doesn't match. Supported types are semver, debian, python, and all:
version('1:1.2.3', type: 'debian')semver() is a deprecated alias for version(). Use version() in new queries.
version.epoch
Return the epoch of a version as an integer, or 0 if it has none.
version('7:1.2.3').epochExample output:
version.epoch: 7version.inRange
Check that a version satisfies two bounds. Each bound can carry an operator (>=, >, <=, <, =, ==, or !=), a ^ or ~ shorthand, or a wildcard such as 1.2.x. A bound without an operator is inclusive: the first is treated as >= and the second as <=.
version('1.2.3').inRange('>= 1.0.0', '< 2.0.0')version('1.9.0').inRange('^1.2.3', '< 3.0.0')A version with nothing numeric in it, such as latest, returns an error.
Type Conversion Functions
Conversion
Convert a value from one type to another with bool(), int(), float(), string(), regex(), dict(), and ip():
int(1.23)Example output:
int: 1More examples:
int("12")
bool(1)
float(12)
string(1.89)
regex("w.r.d") == "world 🌎"
ip(167772160)ip(167772160) returns the IP address 10.0.0.0.
typeof
Return the name of a value's type as a string:
typeof(version("1.2.3"))Example output:
typeof: "version"Dict Functions
A dict holds data whose type isn't known until the query runs, such as parsed JSON. You can call the string, array, and map functions on a dict, and MQL applies them to whatever the dict holds at run time. For example, .length counts the characters of a string value or the entries of an array value.
dict.recurse
Traverse nested dict structures to extract data from mixed value types. This is especially useful for querying complex JSON data where the target values are at varying depths.
Given a JSON structure like:
{
"users": [{ "name": "bob" }],
"owners": {
"admins": [{ "name": "joy", "isOwner": true }]
}
}If that data is in a file named users.json, use recurse to find all entries with a name field, regardless of depth:
parse.json("users.json").params.recurse( name != empty )Example output:
parse.json.params.recurse: [
0: {
name: "bob"
}
1: {
isOwner: true
name: "joy"
}
]Combine recurse with map to extract just the values you need:
parse.json("users.json").params.recurse( name != empty ).map(name)Example output:
parse.json.params.recurse.map: [
0: "bob"
1: "joy"
]Learn more
- Write Effective MQL: see how these functions fit into queries, filters, and assertions.
- Resource reference: the resources and fields you can apply these functions to.
- MQL Overview: where MQL runs and how to get started.