Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extracting value from nested list

Tags:

json

jmespath

The JSON I want to parse looks like this:

{
  "results": [
    [
      {
        "field": "@logStream",
        "value": "i-0d41c4f2b294fae88-messages"
      },
      {
        "field": "@ptr",
        "value": "CmEKJgoiMTI1NzEwNTIwMzE3OkRhdGFJbmdlc3QtZW50ZXJwcmlzZRAHEjUaGAIGPjW1igAAAACsKl4NAAY/k4KwAAAAoiABKIzAjqzoMDC5+ZGs6DA4D0DrEEi4C1DlBxgAEA4YAQ=="
      }
    ]
  ],
  "statistics": {
    "recordsMatched": 94761,
    "recordsScanned": 94761,
    "bytesScanned": 13659575
  },
  "status": "Complete"
}

From each sublist in the results list, I want the value of value for every field that equals @logStream.
How can this be achieved?

The closest I've been able to come to even getting anything that distinguishes field values is this:

results[].[field==`@logStream`] 

But that only gives booleans:

[
  [
    true
  ],
  [
    false
  ]
]

What I'd like to get is this, or something like it:

[
  [
    {
      "value": "i-0d41c4f2b294fae88-messages"
    }
  ]
]

I also tried

results[].[field==`@logStream`].value

and

results[].[field==`@logStream`].[value]

but those only gave me [ null ] and null.

like image 795
Phil Avatar asked Aug 16 '26 22:08

Phil


1 Answers

The biggest issue in your query is the fact that you forgot the question mark ? in order to make a proper filter projection [?someCondition], and not a multiselect .[someAttributeProjectedInAnArray].

The other issue is that you are using a flatten projection [] on your results array without stopping it, which makes it impossible to do the subsequent filter projection you need on the field attribute, where you could have used a [*].

Then, to achieve the selection of the value attribute, you can use a multiselect hash, this time: .{value: value}.

Knowing all this, if you want to achieve exactly the output stated your question, you can use this query:

results[*][?field ==`@logStream`].{value: value}

Wich would yield:

[
  [
    {
      "value": "i-0d41c4f2b294fae88-messages"
    }
  ]
]

You can even go further and flatten the list of lists:

results[*][?field ==`@logStream`][].{value: value}

Would yield:

[
  {
    "value": "i-0d41c4f2b294fae88-messages"
  }
]

Or simplify the multiselect hash in a list projection:

results[*][?field ==`@logStream`][].value

Would yield:

[
  "i-0d41c4f2b294fae88-messages"
]

Or use alternative syntaxes, by keeping your first flatten projection, stop it with a pipe expression, then apply your query:

results[]|[?field ==`@logStream`].{value: value}

Would yield:

[
  {
    "value": "i-0d41c4f2b294fae88-messages"
  }
]

And

results[]|[?field ==`@logStream`].value

Would yield:

[
  "i-0d41c4f2b294fae88-messages"
]
like image 89
β.εηοιτ.βε Avatar answered Aug 19 '26 06:08

β.εηοιτ.βε



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!