skip to Main Content

I’d like to select elements from a list based on the value of bar in the params key-value pair. See example below.

I have the following code:

with open('foobar.json', 'r') as fp:
    data = json.load(fp)
expr = '[].record'
records = jmespath.search(expr, data)

And the following input file (foobar.json)

[   {   'record': {   'name': 'foobar1',
                      'params': [   {'name': 'foo', 'text': '4'},
                                    {'name': 'bar', 'text': '12'}]}},
    {   'record': {   'name': 'foobar2',
                      'params': [   {'name': 'foo', 'text': '4'},
                                    {'name': 'bar', 'text': '16'}]}}]

The JMESPath query returns both records, as expected.

[   {   'name': 'foobar1',
        'params': [   {'name': 'foo', 'text': '4'},
                      {'name': 'bar', 'text': '12'}]},
    {   'name': 'foobar2',
        'params': [   {'name': 'foo', 'text': '4'},
                      {'name': 'bar', 'text': '16'}]}]

I’d like a JMESPath expression that would return only this one record because the text of the entry in params with name bar is greater than or equal to 13.

[   {   'name': 'foobar2',
        'params': [   {'name': 'foo', 'text': '4'},
                      {'name': 'bar', 'text': '16'}]}]

2

Answers


  1. Put the query into a comprehension. For example,

    import json
    import jmespath
    
    fp = open('foobar.json', 'r')
    data = json.load(fp)
    result = [i for i in data if int(jmespath.search('[?name==`bar`].text', i['record']['params'])[0]) >= 13]
    print(json.dumps(result, indent=4))
    

    gives

    [
        {
            "record": {
                "name": "foobar2",
                "params": [
                    {
                        "name": "foo",
                        "text": "4"
                    },
                    {
                        "name": "bar",
                        "text": "16"
                    }
                ]
            }
        }
    ]
    
    Login or Signup to reply.
  2. There is nothing blocking you to make n-levels filter projections in JMESPath.
    So, here, what you are looking for is all element where you will filter the record.params array (first level filter projection) where its elements contains a text greater or equal than thirteen (second level filter projection).

    Which will translate in the query

    [?record.params[?to_number(text) >= `13`]].record
    

    You just. have to feed this in your expr variable to get your desired result.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search