jsonb_set関数

jsonb_set関数はJSON文字列の要素を更新する関数。
以下の書式で定義される。

jsonb_set(target, path, new_value, [create_missing])
  • target: 更新対象のJSON
  • path: 更新する要素のパス
  • new_value: 更新する値
  • create_missing: パスで指定したキーが無い場合に追加しない場合はfalseを指定する

更新する要素のパス

要素のパスは{}の中にカンマ区切りで指定する。
キーバリューの場合はキー名、配列の場合はインデックスを指定する。

例えば以下のようなJSONを考える。

{
  "a": {
    "b": {
      "c": 1
    }
  }
}

上記JSONのcまでのパスは{a, b, c}となる。

配列の場合はインデックスで指定する。
例えば以下のようなJSONの場合。

{
  "a": [
    {
      "b": 1
    },
    {
      "b": 2
    }
  ]
}

1つ目のbまでのパスは{a, 0, b}となり、2つ目のbまでのパスは{a, 1, b}となる。

JSON文字列の要素を更新する

以下のJSONを考える。

{
  "a": {
    "b": {
      "c": 1
    }
  }
}

上記JSONのcの値を2に更新するには以下のようにする。

SELECT jsonb_set('{"a": {"b": {"c": 1}}}', '{a, b, c}', '2');
# => {"a": {"b": {"c": 2}}}

以下の様に配列を含む場合。

{
  "a": [
    {
      "b": 1
    },
    {
      "b": 2
    }
  ]
}

上記JSONの2つ目のbの値を3に更新するには以下のようにする。

SELECT jsonb_set('{"a": [{"b": 1}, {"b": 2}]}', '{a, 1, b}', '3');
# => {"a": [{"b": 1}, {"b": 3}]}

JSON文字列の要素を追加する

デフォルトではパスで指定したキーが無い場合に追加される。

SELECT jsonb_set('{"a": {"b": 1}}', '{a, c}', '2');
# => {"a": {"b": 1, "c": 2}}

上記SQLでは{"a": {"b": 1}}{a, c}のパスにキーが存在しないため、cが追加されている。

パスで指定したキーが無い場合に追加しないようにする

jsonb_setの第4引数にfalseを指定すると、パスで指定したキーが無い場合に追加されない。

SELECT jsonb_set('{"a": {"b": 1}}', '{a, c}', '2', false);
# => {"a": {"b": 1}}

上記SQLでは{"a": {"b": 1}}{a, c}のパスにキーが存在おらず、第4引数にfalseを指定しているため、cが追加されていない。

jsonb_insert関数

jsonb_insert関数はJSON文字列の指定した箇所の配列に要素を追加する関数。
以下の書式で定義される。

jsonb_insert(target, path, new_value, [after])
  • target: 更新対象のJSON
  • path: 更新する要素のパス
  • new_value: 更新する値
  • after: 指定したキーの後に追加する場合はそのキー名を指定する

パスの指定方法はjsonb_setと同じ。

配列に要素を追加する

以下のJSONを考える。

{
  "a": {
    "b": [0, 1, 2]
  }
}

上記JSONのbの配列に3を追加するには以下のようにする。

SELECT jsonb_insert('{"a": {"b": [0, 1, 2]}}', '{a, b, 2}', '3', true);
# => {"a": {"b": [0, 1, 2, 3]}}

インデックスに2を指定し、第4引数にtrueを指定している。

先頭に追加する場合はインデックスを0とし、第4引数にfalseを指定する。

SELECT jsonb_insert('{"a": {"b": [0, 1, 2]}}', '{a, b, 0}', '3', false);
# => {"a": {"b": [3, 0, 1, 2]}}

第4引数のデフォルト値はfalseなので省略してもよい。

SELECT jsonb_insert('{"a": {"b": [0, 1, 2]}}', '{a, b, 0}', '3');
# => {"a": {"b": [3, 0, 1, 2]}}