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?
4
Answers
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, usingIN
withH1
andH2
, which evaluates to a boolean). After the grouping, use amap
to rectify the shapes of the individual groups as desired.Demo
Here is one possible solution which uses of the
,
filter which generates multiple outputs for a single input. It also uses the fact that iterating inside an object "multiplies" this object (generating multiple objects, one for each iterated value)Here’s a straightforward solution using the generic stream-oriented function
aggregate_by/2
:Using
aggregate_by
here not only makes the solution quite straightforwardonce one understands what it does, but also makes the program relatively efficient in comparison to
group_by/1
in that the latter relies on sorting.In case it is helpful to someone: if we start with something very similar to the selected answer, but with minor changes for readability (demo):
we can accommodate an arbitrary complex grouping criteria as follows (demo):
It also keeps all properties except
.country
instead of having to provide a whitelist of values.