3

I was using JQPlay to play around the format. I am not able to understand how to use reduce to group by child structure. I want to group based on the org or the parent id.

just update my jqplay filter, but not able to remove two tags to group by id.

jq play syntax-

I am using below syntax in jqplay.org. Also can you please advise how debug anything after pipe symbol.

.items | {"org" : map( {id : .org, orgProperties : [{"properties" : {"methodId" : [{"id" : .methodId}]}}]})| group_by(.id) | map( reduce .[] as $x (.[0]|{}; .orgProperties+= ($x | .orgProperties)))}

Input JSON

{
  "items": [
    {
      "org": "750141",
      "methodId": "1-10F7IAK7"
    },
    {
      "org": "750141",
      "methodId": "1-10TP18L0"
    },
    {
      "org": "750142",
      "methodId": "1-10TP18L1"
    }
  ]
}

Output JSON

{
  "org": [
    {
      "orgProperties": [
        {
          "properties": {
            "methodId": [
              {
                "id": "1-10F7IAK7"
              }
            ]
          }
        },
        {
          "properties": {
            "methodId": [
              {
                "id": "1-10TP18L0"
              }
            ]
          }
        }
      ]
    },
    {
      "orgProperties": [
        {
          "properties": {
            "methodId": [
              {
                "id": "1-10TP18L1"
              }
            ]
          }
        }
      ]
    }
  ]
}

Expected JSON Output

{
  "org": [
    {
      "id": "750141",
      "orgProperties": [
        {
          "properties": {
            "methodId": [
              {
                "id": "1-10F7IAK7"
              },
              {
                "id": "1-10TP18L0"
              }
            ]
          }
        }
      ]
    },
        {
      "id": "750142",
      "orgProperties": [
        {
          "properties": {
            "methodId": [
              {
                "id": "1-10TP18L1"
              }
            ]
          }
        }
      ]
    }
  ]
} 
0

1 Answer 1

2

You need to do something like below. You need to group_by() and then later do the processing

jq '.items | {org: group_by(.org) | map({id: .[0].org, orgProperties: [{properties: { methodId: map({id: .methodId}) }}]})} ' input.json

I don't think there exists a way to increase the debug verbose level thrown by jq unless probably tinkering with the code to add your own debug statements and run a custom build.

I personally build-up the filter from one component at a time, observe its output and manipulate things on top of that. To break down the functionality of above

  • The JSON is reconstructed completely after the '.items | {org: .. portion of the filter. The result of the subsequent part forms what is now below the top level "org" section the expected output.
  • Once you do a group_by(.org), you get a result that has two array entries, one with 2 objects (id 750141) and the other with a single object (id 750142).
  • Then you run the code inside map(..) to the object list returned from the previous step
  • We only need the unique key name in the final result, so we just use the .[0].org in the first array. This will work even you have multiple repetitive key names. Pause and have a look at the output until this point

    {
      "org": [
        {
          "id": "750141"
        },
        {
          "id": "750142"
        }
      ]
    }
    
  • Now construct the rest of the output with orgProperties: [{properties: { methodId: ... which creates the sub-nodes as

    "orgProperties": [
    {
        "properties": {
            "methodId": 
    
  • Create the final sub array with map({id: .methodId}) to create a key value pair with the list of IDs

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks mate. It worked and great thing is i understood how it is done now. But can you explain why do we use .[0] ... what does it implies.
@user2993735: After the group_by(.org), two arrays are created, the first one with same value .org as 750141. So we are reducing this two into one by using the .[0] which is same as doing .[1]. See the output of .items | {org: group_by(.org)} and see for it yourself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.