Given this json:
{
"hits": [
{
"country": "PT",
"level": "H2",
"id": "id1"
},
{
"country": "PT",
"level": "H1",
"id": "id2"
},
{
"country": "CZ",
"level": "H2",
"id": "id3"
},
{
"country": "IT",
"level": "H2",
"id": "id4"
},
{
"country": "PT",
"level": "H3",
"id": "id5"
},
{
"country": "PT",
"level": "H3",
"id": "id6"
},
{
"country": "PT",
"level": "H4”,
"id": "id7"
}
]
}
I would like to group this by country and in two levels, one having the H1 and H2 entries, and the other having the H3 and H4 entries. Furthermore, I would like that ids and levels to be encapsulated in an object called "entities" like follows:
{
"hits": [
{
"country": "PT",
"entities": [
{
"id": "id2",
"level": "H1"
},
{
"id": "id1",
"level": "H2"
}
]
},
{
"country": "CZ",
"entities": [
{
"id": "id3",
"level": "H2"
}
]
},
{
"country": "IT",
"entities": [
{
"id": "id4",
"level": "H2"
}
]
},
{
"country": "PT",
"entities": [
{
"id": "id5",
"level": "H3"
},
{
"id": "id6",
"level": "H3"
},
{
"id": "id7",
"level": "H4"
},
]
}
]
}
I am quite new to jq. Could anyone help me doing this in jq?
>Solution :
Provide group_by with two criteria: one is simply the value of .country, the other is the containedness of .level in a given set of values (here, using IN with H1 and H2, which evaluates to a boolean). After the grouping, use a map to rectify the shapes of the individual groups as desired.
.hits |= (
group_by(.country, IN(.level; "H1", "H2"))
| map((first | {country}) + {entities: map({id, level})})
)
{
"hits": [
{
"country": "CZ",
"entities": [
{
"id": "id3",
"level": "H2"
}
]
},
{
"country": "IT",
"entities": [
{
"id": "id4",
"level": "H2"
}
]
},
{
"country": "PT",
"entities": [
{
"id": "id5",
"level": "H3"
},
{
"id": "id6",
"level": "H3"
},
{
"id": "id7",
"level": "H4"
}
]
},
{
"country": "PT",
"entities": [
{
"id": "id1",
"level": "H2"
},
{
"id": "id2",
"level": "H1"
}
]
}
]
}