Artifactory query language (AQL). How to write a not match query with $nmatch
JFrog Artifactory is probably the most widely used archiving system currently used in most CI-CD environments. We often need to query Artifactory to find latest artifacts matching a certain criteria, or not matching a certain criteria. Artifactory has such an API but its slightly nuanced compared to other APIs I have come across. It’s a query language to which you pass JSON “like” objects.
Note that the API itself accepts plain text.
To start off you don’t actually pass a valid JSON to the API. Rather its as if you are posting some kind of javascript code to the server.
The actual API is documented here. So for example if I want to list artifacts that match the name property with my-rpm.rpm
. I need to post a body like so.
items.find({
"repo":{"$eq": "my-repo-name"},
"path":{"$match":"*/a_particular_folder"},
"name":{"$match": "my-rpm*.rpm"}
}).sort({"$desc":["created"]}).limit(1)
It returns results like below.
{
"results": [{
"repo": "my-repo-name",
"path": "top_folder/a_particular_folder",
"name": "my-rpm.some-version.release-level.rpm",
"type": "file",
"size": 4690,
"created": "2018-09-20T08:09:50.835-05:00",
"created_by": "someuser@mycom.com",
"modified": "2018-09-24T02:28:54.855-05:00",
"modified_by": "someuser@mycom.com",
"updated": "2018-09-24T02:28:54.855-05:00"
}],
"range": {
"start_pos": 0,
"end_pos": 1,
"total": 1,
"limit": 1
}
}
Note that even the JSON is not really a valid JSON as key values can repeat, so for example if I want to exclude certain names that start with my-rpm
but not including my-rpm-not-this
then I need to use the $nmatch
operator.
So the query for that would be something like below.
items.find({
"repo":{"$eq": "my-repo-name"},
"path":{"$match":"*/a_particular_folder"},
"name":{"$match": "my-rpm*.rpm"},
"name": {"$nmatch":"my-rpm-not-this*.rpm"}
}).sort({"$desc":["created"]}).limit(1)
The above query reads as give all `.rpm` files in `a_particular_folder` that start with my-rpm
but not starting my-rpm-not-this
The curl command is something like below.
curl -X POST -k -H 'Content-Type:text/plain' -H 'X-JFrog-Art-Api: your_api_key' -i 'https://artifactory_hostname/artifactory/api/search/aql' --data 'items.find({
"repo":{"$eq": "my-repo-name"},
"path":{"$match":"*/a_particular_folder"},
"name":{"$match": "my-rpm*.rpm"},
"name": {"$nmatch":"my-rpm-not-this*.rpm"}
}).sort({"$desc":["created"]}).limit(1)
'
You can either use the API key or pass basic authentication using -u
curl parameter. The steps to create an Artifactory API key is here.
That’s it, if you find this article useful do send some claps. In case of any doubts leave a question and I will respond.