I have a simple Ansible play where I want to call a REST endpoint several times. I want to filter the result: only orders where the total for a product is less than 1000. By comparing the number of items in products array and in the resulted array the filtering is working.
The Problem is the result shows only nulls.
---
- hosts: test
#gather_facts: no
vars:
list0: ['a', 'b']
tasks:
- name: Get carts
uri:
url: https://dummyjson.com/carts/1
method: GET
register: carts
loop: "{{ list0 }}"
- debug: msg="{{ carts }}"
- set_fact:
filtered_items: "{{ carts | json_query ('results[*].json.products[?total<`1000`].{id: results[*].item, cart: results[*].json.products}') }}"
cacheable: yes
- debug: msg="{{ filtered_items }}"
This is a small sample of the data:
{
"results":
[
{"item": "a"}
{
"item": "b",
"json": {
"discountedTotal": 89686.65,
"id": 1,
"products": [
{
"discountPercentage": 12.84,
"discountedTotal": 566.5,
"id": 100,
"price": 129.99,
"quantity": 5,
"title": "Apple Airpods",
"total": 649.95
}
]
}
}
]
}
And this is the final result.
"msg": [
{ "cart": null, "id": null },
{ "cart": null, "id": null }
]
It should be something like: [ "id":"b","cart":[{...},{...}] ]
JMESPath does not allow you to go down and up the JSON tree that way. When you are at a specific level everything you are addressing is relative to the level you are at.
So, if, for the moment being, we simplify your query, getting rid of the filter, a correct query won't be
results[*].json.products[*].{
id: results[*].item,
cart: results[*].json.products
}
But rather
results[*].{
id: item,
cart: json.products
}
And because you are interested in the item
field, and that JMESPath does not provide a way to go back up in the JSON tree as answered by the maintainer, you do have to end you filter projection at results[*]
and begin your object projection there.
Now, to fit your condition back in, you'll just have to apply the same idea and fit the filtering in results[*]
, which become results[?json.products[?total<`1000`]]
.
Your query end up being:
results[?json.products[?total<`1000`]].{
id: item,
cart: json.products
}