5

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

Max Murphy
  • 1,701
  • 1
  • 19
  • 29

1 Answers1

18

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.

Konstantin Suvorov
  • 65,183
  • 9
  • 162
  • 193
  • 1
    Thank you! When looking at why your answer worked I realised that the json_query filter uses jmespath, not node's or python's jsonpath. Using the right language reference helps! Thanks a lot! – Max Murphy Dec 22 '16 at 19:20