Home > database >  Transform JSON array to object with jq
Transform JSON array to object with jq

Time:01-25

I'm trying to transform array to object by specific key. It works fine without using stream, but not possible when stream is applied.

Data:

[
  {
    "id": "1",
    "userId": "fa51531d"
    }
    ,
    {
    "id": "2",
    "userId": "a167869a"
  }
]

I tried running this command but it throws an error.

jq -n --stream 'fromstream(1|truncate_stream(inputs)) | INDEX(.id)' test.json > result.json

Data above should be transformed to:

{
  "1": {
    "userId": "fa51531d",
    "id": "1"
  },
  "2": {
    "userId": "a167869a",
    "id": "2"
  },
}

I want to achieve the same result as with jq 'INDEX(.id) but I need to use stream (because of big JSON file).

CodePudding user response:

If you are trying to recreate the whole input object, the stream-based approach is rendered pointless. That said, using this approach, there's no need to truncate. So either replace 1 with 0:

jq -n --stream 'fromstream(0|truncate_stream(inputs)) | INDEX(.id)'

Or just omit it entirely (which reveals its futility):

jq -n --stream 'fromstream(inputs) | INDEX(.id)'

What would make more sense, is to output a stream of objects, each indexed as with INDEX. Maybe you were looking for this:

jq -n --stream 'fromstream(1|truncate_stream(inputs)) | {(.id):.}'
{
  "1": {
    "id": "1",
    "userId": "fa51531d"
  }
}
{
  "2": {
    "id": "2",
    "userId": "a167869a"
  }
}

CodePudding user response:

To transform your JSON Array to JSON Object maybe you can use this

jq reduce .[] as $item ({}; .[$item.id] = $item)

but if you want to stream the JSON, i don't have the solutions

cmiiw

CodePudding user response:

If your stream really looks like in your question, this should do:

jq 'INDEX(.id)' test.json

Output:

{
  "1": {
    "id": "1",
    "userId": "fa51531d"
  },
  "2": {
    "id": "2",
    "userId": "a167869a"
  }
}
  • Related