1

I have a json type column config I want to add a key value pair into, ultimately looking like:

{
  "features": {
    "divisions": true,
    "utilities": {
        "water": true,
        "gas": true,
        "electric": true
    }
  }
}

The issue I'm running into is when I want to insert the utilities object inside of features, I either overwrite the divisions key value or I'm returning NULL and the utilities object isn't being inserted.

Furthermore, the config column may be NULL or initially just be an empty {}.

This query will check for NULL or empty {} and also whether the features key exists but results in overwriting features if it already exists:

UPDATE entities SET config = JSON_SET(COALESCE(config, '{}'),
  COALESCE("$.features", "features"), JSON_OBJECT("utilities", 
  JSON_OBJECT("water", TRUE, "gas", TRUE, "electric", TRUE))) 
  WHERE id = 123725082;

This works fine unless the column already contains something like:

{
  "features": {
    "divisions": true,
  }
}

in which it overwrites divisions with the utilities object.

So I'm trying a JSON_INSERT query; from what I've gathered from mysql json functions documentation should work but it's returning null and I can't understand why:

UPDATE entities SET config = JSON_INSERT(COALESCE(config, '{}'),
  COALESCE("$.features", "features"), JSON_OBJECT("utilities", 
  JSON_OBJECT("water", TRUE, "gas", TRUE, "electric", TRUE))) 
  WHERE id = 123725082;
2
  • What's the point of COALESCE("$.features", "features")? It's the same as just "$.features". Commented Oct 31, 2017 at 20:33
  • I'm having trouble coming up with the full expression, but I think you need a mix of JSON_EXTRACT and COALESCE calls to handle missing properties at each level of the JSON structure. Commented Oct 31, 2017 at 20:43

1 Answer 1

6

JSON_MERGE function can be useful in this case.

Modify the UPDATE as needed:

UPDATE `entities`
  SET `config` = COALESCE(
    JSON_MERGE(
      `config`,
      JSON_OBJECT('features',
        JSON_OBJECT('utilities',
          JSON_OBJECT('water', TRUE, 'gas', TRUE, 'electric', TRUE)
        )
      )
    ),
    JSON_INSERT(
      JSON_OBJECT(),
      '$.features',
       JSON_OBJECT('utilities',
         JSON_OBJECT('water', TRUE, 'gas', TRUE, 'electric', TRUE)
       )
    )
  );

See db-fiddle.

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

1 Comment

The fiddle helped me out quite a bit to figure out these methods, thanks :)

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.