Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flatten a JSON document using jq

Tags:

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.

like image 878
Dror Avatar asked Jul 11 '14 12:07

Dror


People also ask

How do I flatten a JSON object?

Flatten a JSON object: var flatten = (function (isArray, wrapped) { return function (table) { return reduce("", {}, table); }; function reduce(path, accumulator, table) { if (isArray(table)) { var length = table.

Can jq write JSON?

jq is an amazing little command line utility for working with JSON data.

Does jq use JSONPath?

JSONPath distinguishes between the "root object or element" ($) and "the current object or element" (.). jq simply uses . to refer to the current JSON entity and so it is context-dependent: it can refer to items in the input stream of the jq process as a whole, or to the output of a filter.

What is jq format?

jq is a free open source JSON processor that is flexible and straightforward to use. It allows users to display a JSON file using standard formatting, or to retrieve certain records or attribute-value pairs from it.


Video Answer


1 Answers

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

  1. For every item in the array...

    map(...) 
  2. Create a new object containing the values for all except the fields property.

    with_entries(select(.key != "fields")) 
  3. Combine that with...

    + 
  4. Each of the fields projecting each of the values to the first item of each array

    (.fields | with_entries(.value = .value[0])) 
like image 91
Jeff Mercado Avatar answered Sep 20 '22 13:09

Jeff Mercado