Array and String cannot have their containment checked error when trying to search array using jq

Viewed 1491

I have a json file that looks roughly like this:

{
    "default": [
        {
            "name" : "Joe Bloggs",
            "email" : "joe.bloggs@business.org"
        }
    ],
    "groups": [
        {
            "recipients" : [
                {
                    "name" : "Jane Bloggs",
                    "email" : "jane.bloggs@business.org"
                }
            ],
            "orgs" : [  
                "Service A",
                "Service B",
                "Service C"
            ]
        },
        {
            "recipients" : [
                {
                    "name" : "Bill Gates",
                    "email" : "bill.gates@business.org"
                }
            ],
            "orgs" : [
                "Service D",
                "Service E"
            ]
        },
        {   
            "recipients" : [
                {
                    "name" : "Steve Jobs",
                    "email" : "steve.jobs@me.com"
                }
            ],
            "orgs" : [
                "Service F",
                "Service G"
            ]
        }
    ]
}

Using jq I want to be able to search using one of the orgs, so for example 'Service A' and return only the recipients information

I can search recipients easy enough using jq like:

cat /path/to/file.json | jq -r '.groups[] | .recipients[] | select(.name | contains("Jobs"))' )

to return

{
  "name": "Steve Jobs",
  "email": "steve.jobs@me.com"
}

But If I try to search via the orgs array, I get an error:

cat /path/to/file.json | jq -r '.groups[] | select(.orgs | contains("Service A"))' )
jq: error (at <stdin>:46): array (["Service A...) and string ("Service A") cannot have their containment checked

Is it possible to do what I am looking for with jq?

1 Answers

Instead off contains you'll need index [docs] to check if there's an index with the value Service A:

.groups[] | select(.orgs | index("Service A"))

Will output:

{
  "recipients": [
    {
      "name": "Jane Bloggs",
      "email": "jane.bloggs@business.org"
    }
  ],
  "orgs": [
    "Service A",
    "Service B",
    "Service C"
  ]
}
JqPlay demo

We can extend that to output only the recipients like so:

.groups[] | select(.orgs | index("Service A")) | .recipients | first

Where we use first to select the first object from the .recipients array. The output will be:

{
  "name": "Jane Bloggs",
  "email": "jane.bloggs@business.org"
}
JqPlay demo
Related