*Abstract*
I would like to contribute a new jq() filter to Ansible, exposing the jq 
expression language. This would complement the existing json_query() 
filter, based on jmespath expressions. I wanted to see if such a filter 
would be welcome, either as PR to Ansible itself, or a third party module 
through Ansible Galaxy

*Background*
jq is an expression language used for filtering and transforming JSON data. 
It is mostly commonly used through the jq command, to filter JSON in a 
pipeline.

Examples of jq command
$ echo '[{"x":1, "y":2}, {"x":11}]' | jq .[0].x
1

$ echo '[{"x":1, "y":2}, {"x":11}]' | jq '[.[] | .x]'
[
  1,
  11
]

*Motivation*
There are some operations expressible with jq that are not expressible with 
jmespath. The one I have encountered is producing a flat list of objects, 
from a list of objects each with a nested list of something. e.g. 

$ cat databases.json
[
  {"db": "a", "users": [{"name": "alice"}, {"name": "alex"}]},
  {"db": "b", "users": [{"name": "bob"}, {"name": "brienne"}]}
]
$ cat databases.json | jq '. | map({db, name: .users[].name})'
[
  {
    "db": "a",
    "name": "alice"
  },
  {
    "db": "a",
    "name": "alex"
  },
  {
    "db": "b",
    "name": "bob"
  },
  {
    "db": "b",
    "name": "brienne"
  }
]

*Design*
The filter would be invoked in a similar manner to the json_query() filter

Mockup:
$ ansible localhost -mdebug -a'{{ [{"x":1, "y":2}, {"x":11}] | jq('[.[] | 
.x]') }}'
localhost | SUCCESS => {
    "msg": [
        1, 
        11
    ]
}

Initially jq features such as jq arguments/variables would be excluded.

*Implementation*
The filter would expose one of the existing Python bindings to libjq, the C 
library on which the jq command is built.

*Alternatives*
The json_query() filter (based on jmespath) covers much of the same 
functionality as jq. The few cases where jmespath cannot implement a 
particular operation alone could be overcome by supplementing with other 
filters, e.g.

{{ databases | subelements('users')
              | to_json | from_json
              | json_query('[*].{db: [0].db, name: [1].name}')
}}

would produce the same result as the proposed {{ databases | jq('. | 
map({db, name: .users[].name})') }}.

References
https://stedolan.github.io/jq/
https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#json-query-filter
https://stackoverflow.com/questions/54160360/jmespath-expression-to-flatten-array-of-objects-each-with-nested-arrays-of-obje
https://jqplay.org/s/5YHjzcspb5
https://pypi.org/project/jq/
https://pypi.org/project/pyjq/

-- 
You received this message because you are subscribed to the Google Groups 
"Ansible Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to ansible-devel+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to