dks551
dks551

Reputation: 1113

Add or Update a field in one JSON file from another JSON file based on matching field

I have two JSON files a.json and b.json. The contents in a.json file is a JSON object and inside b.json its an array.I want to add/update status field in each mappings in a.json by retrieving the value from b.json file.
a.json:

{
  "title": 25886,
  "data": {
    "request": {
      "c": 46369,
      "t1": 1562050127.376641
    },
  },
  "rs": {
    "mappings": {
      "12345": {
        "id": "12345",
        "name": "test",
        "customer_id": "11228",
      },
      "45678": {
        "id": "45678",
        "name": "abc",
        "customer_id": "11206",
      }
    }
}}

b.json:

[
  {
    "status": "pending",
    "extra": {
      "name": "test"
    },
    "enabled": true,
    "id": "12345"
  },
  {
    "status": "not_started",
    "extra": {
      "name": "abc"
    },
    "enabled": true,
    "id": "45678"
  }
]

Below is my expected output:

{
  "title": 25886,
  "data": {
    "request": {
      "c": 46369,
      "t1": 1562050127.376641
    },
  },
  "rs": {
    "mappings": {
      "12345": {
        "id": "12345",
        "name": "test",
        "customer_id": "11228",
        "status":"pending"
      },
      "45678": {
        "id": "45678",
        "name": "abc",
        "customer_id": "11206",
        "status":"not_started"
      }
    }
}}

In this expected JSON file we have status field whose value is retrieved from b.json file based on a matching id value. How to do this using jq ?

Upvotes: 0

Views: 1272

Answers (1)

peak
peak

Reputation: 116640

For the purposes of this problem, b.json essentially defines a dictionary, so for simplicity, efficiency and perhaps elegance, it make sense to start by using the builtin function INDEX to create the relevant dictionary:

INDEX( $b[] | {id, status}; .id )

This assumes an invocation of jq along the lines of:

jq --argfile b b.json -f update.jq a.json

(Yes, I know --argfile has been deprecated. Feel free to choose another way to set $b to the contents of b.json.)

Now, to perform the update, it will be simplest to use the "update" operator, |=, in conjunction with map_values. (Feel free to check the jq manual :-)

Putting everything together:

INDEX( $b[] | {id, status}; .id ) as $dict
| .rs.mappings |= map_values( .status = $dict[.id].status )

Upvotes: 1

Related Questions