In previous tutorials we’ve taken a brief look at the Oracle Cloud Infrastructure (OCI) command line interface (CLI). You can explore all of the options available in the docs, but today we’re going to look at the --query flag and how to use it for more advanced filtering of response data.

The default JSON-formatted response from the CLI can be very verbose, containing a lot of info you don’t need, and making the info you do need that much harder to extract. The --query flag takes an argument in the form of a JMESPath string, allowing you to query and filter the response, outputting just what you need. This can be a simple query like [?name=='blocktest'] as we covered in the last article, but it can also be a more advanced query that both filters the input and shapes the output.

For example, let’s write a query that searches not for an exact title match, but for titles that simply contains our search text. To do this, we use the contains function:


data[?contains("display-name", 'your_text_here')]

The key for the base array returned from the CLI is always called data. Within that array, the above example searches for a key in each element called ‘display-name’, and then tests to see whether it contains the text ‘your_text_here’.

The --query flag always assumes a string value. To do numeric comparisons, be sure to cast the value to a number using .to_number(@). For example:


oci compute image list -c $compOcid --query 'data[?"operating-system-version".to_number(@) > `8`]'

There are several functions available in JMESPath, including max_by to return the result with the highest value for a given key, or min_by to return the lowest result. See the JMESPath documentation for more details.

Piping and Negating

You can combine multiple criteria using pipes (|), and you can invert a function by using ?!FUNCTION. For example, if you wanted to search first for a container name, and then remove a set of matches, you could use:


oci compute image list --compartment-id ocid1.tenancy.xxx --query 'data[?contains("display-name",'Oracle-Linux')] | [?!contains("display-name",'arch64')]|[0:1].["display-name",id]' --all

Note the pipe in the middle of the query, which causes the results of the first ?contains search to be “piped” into a negative ?!contains search to remove all images with arch64 in the display name.

Shaping

You can control what information is output as well. To output a specific key path, you can separate each element in the path with a dot, being sure to quote any keys that have a dash in them. For example, to output all of the CreatedBy tags for an OCI compartment listing, you could use:


oci iam compartment list --all --query 'data[*]."defined-tags"."Oracle-Tags".CreatedBy'

This will iterate through the array, and within each hash in the array, locate the “defined-tags” key, find “Oracle-Tags” inside of it, then find the “CreatedBy” key and output its value.

You can also create a custom hash with the output using a syntax like:


--query 'data[*].{id: id, timeCreated: "time-created"}'

The left half of each key/value pair defines the key that will be output, the right half defines what value will be attributed to it. So you’re defining custom keys for existing values in the output.

Now that you see some of the possibilities for these queries, you’re probably wondering how to make them easier to access and more reusable. The CLI has the solution, in the form of aliases you can define in your configuration. Stay tuned for the next article for a look at the three types of aliases you can create and how to use them.