Flatten a JSON document using jq

jq, json

Solution

This one was a tricky one to craft.

map
(
    with_entries(select(.key != "fields"))
    +
    (.fields | with_entries(.value = .value[0]))
)

Let's break it down and explain the bits of it

For every item in the array...

map(...)

Create a new object containing the values for all except the `fields` property.

with_entries(select(.key != "fields"))

Combine that with...

+

Each of the `fields` projecting each of the values to the first item of each array

(.fields | with_entries(.value = .value[0]))

Problem

I'm considering the following array of JSON objects: ``` [ { "index": "index1", "type": "type1", "id": "id1", "fields": { "deviceOs": [ "Android" ], "deviceID": [ "deviceID1" ], "type": [ "type" ], "country": [ "DE" ] } }, { "index": "index2", "type": "type2", "id": "id2", "fields": { "deviceOs": [ "Android" ], "deviceID": [ "deviceID2" ], "type": [ "type" ], "country": [ "US" ] } } ] ``` and I would like to flatten it to get: ``` [ { "index": "index1", "type": "type", "id": "id1", "deviceOs": "Android", "deviceID": "deviceID1", "country": "DE" }, { "index": "index2", "type": "type", "id": "id2", "deviceOs": "Android", "deviceID": "deviceID2", "country": "US" } ] ``` I'm trying to work with `jq` but I fail to flatten the `"fields"`. How should I do it? At the moment I'm interested in command-line tools, but I'm open to other suggestions as well.

Original source