3

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.

β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83
Phil
  • 101
  • 1
  • 5

1 Answers1

1

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"
]
β.εηοιτ.βε
  • 33,893
  • 13
  • 69
  • 83
  • Wow. Thorough answer. Thanks. After I posted my question -- and before I had a chance to come back here and post an answer to my own question -- I went and found me a good JMESPath tutorial, read more carefully the bits I was rusty in, and came up with an answer of my own, which matches *nearly* exactly one of the ones you provided, except that I did the flattening in a different place, but to the same effect: ```results[*][?field==`@logStream`].value[]``` c.f. your: ```results[*][?field==`@logStream`][].value``` Anyway, thanks again. – Phil Feb 26 '23 at 17:22