ansible json-query path to select item by content

Max Murphy picture Max Murphy · Dec 21, 2016 · Viewed 20.1k times · Source

Does anyone know what json-query filter can be used to select Tigger's food in the sample JSON below? The JSON is a simplified stand-in for a massive and relatively complicated AWS blob.

Some background: I was rather pleased to discover that Ansible has a json-query filter. Given that I was trying to select an element from an AWS JSON blob this looked as if it was just what I needed. However I quickly ran into trouble because the AWS objects have tags and I needed to select items by tag.

I tried selector paths equivalent to Foods[Tags[(Key='For') & (Value='Tigger')]] and similar but didn't manage to get it to work. Using a standalone json-query library such as https://www.npmjs.com/package/json-query I can use the parent attribute but that does not appear to be in Ansible, quite apart from being a deviation from the core idea of json-query.

It might be better to sidestep the problem and use a jsonpath selector. jsonpath is similar to json-query and is a translation from xpath.

{ "Foods" :
  [ { "Id": 456
    , "Tags":
      [ {"Key":"For", "Value":"Heffalump"}
      , {"Key":"Purpose", "Value":"Food"}
      ]
    }
  , { "Id": 678
    , "Tags":
      [ {"Key":"For", "Value":"Tigger"}
      , {"Key":"Purpose", "Value":"Food"}
      ]
    }
  , { "Id": 911
    , "Tags":
      [ {"Key":"For", "Value":"Roo"}
      , {"Key":"Purpose", "Value":"Food"}
      ]
    }
  ]
}

References

Answer

Konstantin Suvorov picture Konstantin Suvorov · Dec 21, 2016

Do you need list of ids? If so, try:

- debug: msg="{{ lookup('file','test.json') | from_json | json_query(query) }}"
  vars:
    query: "Foods[].{id: Id, for: (Tags[?Key=='For'].Value)[0]} | [?for=='Tigger'].id"

First construct simple objects with necessary fields and then pipe it to a filter.