bjb
bjb

Reputation: 173

How to JQ select a record where a sub-node matches both values

I have a JSON similar to the following. I have multiple records, and I'm trying to extract the field value for "RecType" from the record which has the tag where Key==name and Value==uiop.

{
  "Records": [
    {
      "RecType": "type-A",
      "Tags": [
        {
          "Key": "category",
          "Value": "foo"
        },
        {
          "Key": "name",
          "Value": "qwerty"
        }
      ]
    },
    {
      "RecType": "type-B",
      "Tags": [
        {
          "Key": "category",
          "Value": "bar"
        },
        {
          "Key": "name",
          "Value": "uiop"
        }
      ]
    }
  ]
}

I've been trying to do the command below, but it returns the RecType for BOTH records, presumably because the Key==Name appears in both. But what I'm trying to do is pull the record where the Key/Value pair where name==uiop; I think what I'm doing is saying "pull all records where there is a Key==name AND Value==uiop which is not the intent.

jq ".Records[] | (select(.Tags[].Key==\"Name\")) 
               | (select(.Tags[].Value==\"uiop\"))" 
               | jq ".RecType" 

I've tried doing an "and" for the two select statements, but it seems to result in booleans, not the matching I'm hoping for.

Any ideas?

Upvotes: 1

Views: 61

Answers (2)

ikegami
ikegami

Reputation: 386541

An alternate approach:

.Records[] | select( .Tags | from_entries | .name == "uiop" ) | .RecType

from_entries turns

[
    {
        "Key": "category",
        "Value": "bar"
    },
    {
        "Key": "name",
        "Value": "uiop"
    }
]

into

{
    "category": "bar",
    "name": "uiop"
}

Upvotes: 1

Fravadona
Fravadona

Reputation: 17216

You were close, it's just that you need to nest your selects:

.Records[] |
select(
    .Tags[] |
    select(.Key == "name" and .Value == "uiop")
) |
.RecType

Upvotes: 1

Related Questions