Recursively Parsing Nested JSON with PostgreSQL

Viewed 22

I'm trying to parse a nested JSON in Postgres, which has the following structure:

{
  "id": "Hrr3yh_Bgbf3sS35cI5g1",
  "title": "Test Porcedure",
  "notes": "",
  "revision": "",
  "status": "COMPLETED",
  "description": "N/A",
  "create_date": "2022-09-01T15: 28: 01.144Z",
  "update_date": "2022-09-01T15: 28: 01.144Z",
  "items": [
    {
      "id": "Wd4FxS3J6O4yAwES20E27",
      "type": "SECTION",
      "items": [
        {
          "id": "cYgmal2OzkA6satAyA30M",
          "type": "GROUP",
          "items": [
            {
              "id": "tVhFnDUIOnAjW5uBagnEp",
              "na": true,
              "skip": false,
              "type": "PASS/FAIL",
              "warn": true,
              "label": "",
              "_group": "cYgmal2OzkA6satAyA30M",
              "section_id": "Wd4FxS3J6O4yAwES20E27",
              "description": ""
            },
            {
              "id": "JeUUbwcSEpSPHqSM_SmUL",
              "na": true,
              "skip": false,
              "type": "YES/NO",
              "warn": true,
              "label": "",
              "_group": "cYgmal2OzkA6satAyA30M",
              "section_id": "Wd4FxS3J6O4yAwES20E27",
              "test_types": "AFFIRMATIVE_PASS",
              "description": ""
            },
            {
              "id": "hsx6tdMuAnSfKXJ1FNV5_",
              "na": false,
              "skip": false,
              "type": "TASK ITEM",
              "warn": false,
              "label": "",
              "_group": "cYgmal2OzkA6satAyA30M",
              "repeat": 1,
              "section_id": "Wd4FxS3J6O4yAwES20E27",
              "description": "",
              "checkbox_label": "Completed"
            }
          ],
          "section_id": "Wd4FxS3J6O4yAwES20E27"
        },
        {
          "id": "6y0kWDg9T4g0DmAzlSOkj",
          "type": "INSTRUCTION",
          "title": "",
          "content": "",
          "infoPanel": "none",
          "section_id": "Wd4FxS3J6O4yAwES20E27"
        },
        {
          "id": "595O0C-eEN2A0oQvZ7uuj",
          "type": "GROUP",
          "items": [
            {
              "id": "MWb-KkigeaJCHUIBMV4YX",
              "na": false,
              "skip": false,
              "type": "YES/NO",
              "warn": false,
              "label": "",
              "_group": "595O0C-eEN2A0oQvZ7uuj",
              "section_id": "Wd4FxS3J6O4yAwES20E27",
              "test_types": "AFFIRMATIVE_PASS",
              "description": ""
            },
            {
              "id": "chY0siMNszJNcdtcFoFIJ",
              "na": false,
              "skip": false,
              "type": "YES/NO",
              "warn": false,
              "label": "",
              "_group": "595O0C-eEN2A0oQvZ7uuj",
              "section_id": "Wd4FxS3J6O4yAwES20E27",
              "test_types": "AFFIRMATIVE_PASS",
              "description": ""
            },
            {
              "id": "t4EX6FpooalFGv0MKr6cv",
              "na": false,
              "skip": false,
              "type": "PASS/FAIL",
              "warn": false,
              "label": "",
              "_group": "595O0C-eEN2A0oQvZ7uuj",
              "section_id": "Wd4FxS3J6O4yAwES20E27",
              "description": ""
            },
            {
              "id": "hS-3DZJ3S5fOMo24kH5ZQ",
              "na": false,
              "skip": false,
              "type": "YES/NO",
              "warn": false,
              "label": "",
              "_group": "595O0C-eEN2A0oQvZ7uuj",
              "section_id": "Wd4FxS3J6O4yAwES20E27",
              "test_types": "AFFIRMATIVE_PASS",
              "description": ""
            }
          ],
          "section_id": "Wd4FxS3J6O4yAwES20E27"
        },
        {
          "id": "FteFQ173r1dfI310xkljO",
          "url": "",
          "type": "CUSTOM",
          "label": "",
          "section_id": "Wd4FxS3J6O4yAwES20E27",
          "description": "",
          "configuration": ""
        },
        {
          "id": "swgsqHl1BkJuSA9AjoS7h",
          "type": "GROUP",
          "items": [
            {
              "id": "EnEben7GwMCYM4qdGQUN6",
              "na": false,
              "skip": false,
              "type": "PASS/FAIL",
              "warn": false,
              "label": "",
              "_group": "swgsqHl1BkJuSA9AjoS7h",
              "section_id": "Wd4FxS3J6O4yAwES20E27",
              "description": ""
            }
          ],
          "section_id": "Wd4FxS3J6O4yAwES20E27"
        },
        {
          "id": "dDpKHg2E-Vj2UjOZsGiVD",
          "type": "SUB-SECTION",
          "items": [
            {
              "id": "yVrtKVS2xrLMUsxT3jd2S",
              "type": "GROUP",
              "items": [
                {
                  "id": "D5zareFNaNbqH7MqA9tM0",
                  "na": false,
                  "skip": false,
                  "type": "PASS/FAIL",
                  "warn": false,
                  "label": "",
                  "_group": "yVrtKVS2xrLMUsxT3jd2S",
                  "section_id": "Wd4FxS3J6O4yAwES20E27",
                  "description": ""
                },
                {
                  "id": "sSBLzmxxHBK67C8-bwcwt",
                  "na": false,
                  "skip": false,
                  "type": "PASS/FAIL",
                  "warn": false,
                  "label": "",
                  "_group": "yVrtKVS2xrLMUsxT3jd2S",
                  "section_id": "Wd4FxS3J6O4yAwES20E27",
                  "description": ""
                },
                {
                  "id": "GP9_oCLOI58cqvqWRiwAB",
                  "na": false,
                  "skip": false,
                  "type": "TASK ITEM",
                  "warn": false,
                  "label": "",
                  "_group": "yVrtKVS2xrLMUsxT3jd2S",
                  "repeat": 1,
                  "section_id": "Wd4FxS3J6O4yAwES20E27",
                  "description": "",
                  "checkbox_label": "Completed"
                }
              ],
              "section_id": "Wd4FxS3J6O4yAwES20E27"
            },
            {
              "id": "9OhCrZ5q4YKxd1iTT_gMj",
              "url": "",
              "type": "CUSTOM",
              "label": "",
              "section_id": "Wd4FxS3J6O4yAwES20E27",
              "description": "",
              "configuration": ""
            },
            {
              "id": "WKe1gv30O8C4aKp8ABTRh",
              "type": "INSTRUCTION",
              "title": "",
              "content": "",
              "infoPanel": "none",
              "section_id": "Wd4FxS3J6O4yAwES20E27"
            },
            {
              "id": "pzQm1B7UU6QpWMDK4JATW",
              "type": "GROUP",
              "items": [
                {
                  "id": "-s3GDJC9QyAKeFmM9nsN2",
                  "na": false,
                  "skip": false,
                  "type": "YES/NO",
                  "warn": false,
                  "label": "",
                  "_group": "pzQm1B7UU6QpWMDK4JATW",
                  "section_id": "Wd4FxS3J6O4yAwES20E27",
                  "test_types": "AFFIRMATIVE_PASS",
                  "description": ""
                }
              ],
              "section_id": "Wd4FxS3J6O4yAwES20E27"
            }
          ],
          "steps": [
            "D5zareFNaNbqH7MqA9tM0",
            "sSBLzmxxHBK67C8-bwcwt",
            "GP9_oCLOI58cqvqWRiwAB",
            "9OhCrZ5q4YKxd1iTT_gMj",
            "WKe1gv30O8C4aKp8ABTRh",
            "-s3GDJC9QyAKeFmM9nsN2"
          ],
          "title": "",
          "section_id": "Wd4FxS3J6O4yAwES20E27"
        },
        {
          "id": "xVva0BjGyVM4ihDHFmhfo",
          "type": "GROUP",
          "items": [
            {
              "id": "68YvSQ16j1uy33bvAYqwj",
              "na": false,
              "skip": false,
              "type": "TASK ITEM",
              "warn": false,
              "label": "",
              "_group": "xVva0BjGyVM4ihDHFmhfo",
              "repeat": 1,
              "section_id": "Wd4FxS3J6O4yAwES20E27",
              "description": "",
              "checkbox_label": "Completed"
            },
            {
              "id": "Di-krlCIFct2CPjh3otxn",
              "na": false,
              "skip": false,
              "type": "PASS/FAIL",
              "warn": false,
              "label": "",
              "_group": "xVva0BjGyVM4ihDHFmhfo",
              "section_id": "Wd4FxS3J6O4yAwES20E27",
              "description": ""
            },
            {
              "id": "WlrESfoGPU2s4Rqu37ydY",
              "na": false,
              "skip": false,
              "type": "TASK ITEM",
              "warn": false,
              "label": "",
              "_group": "xVva0BjGyVM4ihDHFmhfo",
              "repeat": 1,
              "section_id": "Wd4FxS3J6O4yAwES20E27",
              "description": "",
              "checkbox_label": "Completed"
            }
          ],
          "section_id": "Wd4FxS3J6O4yAwES20E27"
        }
      ],
      "steps": [
        "tVhFnDUIOnAjW5uBagnEp",
        "JeUUbwcSEpSPHqSM_SmUL",
        "hsx6tdMuAnSfKXJ1FNV5_",
        "6y0kWDg9T4g0DmAzlSOkj",
        "MWb-KkigeaJCHUIBMV4YX",
        "chY0siMNszJNcdtcFoFIJ",
        "t4EX6FpooalFGv0MKr6cv",
        "hS-3DZJ3S5fOMo24kH5ZQ",
        "FteFQ173r1dfI310xkljO",
        "EnEben7GwMCYM4qdGQUN6",
        "dDpKHg2E-Vj2UjOZsGiVD",
        "68YvSQ16j1uy33bvAYqwj",
        "Di-krlCIFct2CPjh3otxn",
        "WlrESfoGPU2s4Rqu37ydY"
      ],
      "title": ""
    },
    {
      "id": "vYAk7eXnwjyJaX72cVRmb",
      "type": "SECTION",
      "items": [
        {
          "id": "ykpItUktwJvRZTfLGUaQ5",
          "type": "GROUP",
          "items": [
            {
              "id": "lsxj_K_Cu-dTOXeMy6N1r",
              "na": true,
              "skip": false,
              "type": "PASS/FAIL",
              "warn": false,
              "label": "",
              "_group": "ykpItUktwJvRZTfLGUaQ5",
              "section_id": "vYAk7eXnwjyJaX72cVRmb",
              "description": ""
            },
            {
              "id": "-Uum_WruYDefivd3iTC_A",
              "na": false,
              "skip": false,
              "type": "YES/NO",
              "warn": false,
              "label": "",
              "_group": "ykpItUktwJvRZTfLGUaQ5",
              "section_id": "vYAk7eXnwjyJaX72cVRmb",
              "test_types": "AFFIRMATIVE_PASS",
              "description": ""
            }
          ],
          "section_id": "vYAk7eXnwjyJaX72cVRmb"
        },
        {
          "id": "UcV8YBrF9SgI13fZZu7S7",
          "type": "SUB-SECTION",
          "items": [
            {
              "id": "2IOdE_PjqEtvlVLg4xjP8",
              "type": "GROUP",
              "items": [
                {
                  "id": "dXho5RxV1mqIYD7esfhmq",
                  "na": false,
                  "skip": false,
                  "type": "PASS/FAIL",
                  "warn": false,
                  "label": "",
                  "_group": "2IOdE_PjqEtvlVLg4xjP8",
                  "section_id": "vYAk7eXnwjyJaX72cVRmb",
                  "description": ""
                },
                {
                  "id": "3_TOIjyYcqd_dP2fIgcoQ",
                  "na": false,
                  "skip": false,
                  "type": "YES/NO",
                  "warn": false,
                  "label": "",
                  "_group": "2IOdE_PjqEtvlVLg4xjP8",
                  "section_id": "vYAk7eXnwjyJaX72cVRmb",
                  "test_types": "AFFIRMATIVE_PASS",
                  "description": ""
                }
              ],
              "section_id": "vYAk7eXnwjyJaX72cVRmb"
            },
            {
              "id": "5BMP1oU6RX_OUwUfm61ry",
              "type": "INSTRUCTION",
              "title": "",
              "content": "",
              "infoPanel": "none",
              "section_id": "vYAk7eXnwjyJaX72cVRmb"
            },
            {
              "id": "6lSvHOLIykr43zthdaQBG",
              "url": "",
              "type": "CUSTOM",
              "label": "",
              "section_id": "vYAk7eXnwjyJaX72cVRmb",
              "description": "",
              "configuration": ""
            }
          ],
          "steps": [
            "dXho5RxV1mqIYD7esfhmq",
            "3_TOIjyYcqd_dP2fIgcoQ",
            "5BMP1oU6RX_OUwUfm61ry",
            "6lSvHOLIykr43zthdaQBG"
          ],
          "title": "",
          "section_id": "vYAk7eXnwjyJaX72cVRmb"
        },
        {
          "id": "NdQu7KDZAzHgC0kV2a5N9",
          "type": "GROUP",
          "items": [
            {
              "id": "ln6JCUpOIIy2dddDv6ZcI",
              "na": false,
              "skip": false,
              "type": "YES/NO",
              "warn": false,
              "label": "",
              "_group": "NdQu7KDZAzHgC0kV2a5N9",
              "section_id": "vYAk7eXnwjyJaX72cVRmb",
              "test_types": "AFFIRMATIVE_PASS",
              "description": ""
            },
            {
              "id": "j7l8s3g8wEp7s3PUW2v-q",
              "na": false,
              "skip": false,
              "type": "YES/NO",
              "warn": false,
              "label": "",
              "_group": "NdQu7KDZAzHgC0kV2a5N9",
              "section_id": "vYAk7eXnwjyJaX72cVRmb",
              "test_types": "AFFIRMATIVE_PASS",
              "description": ""
            }
          ],
          "section_id": "vYAk7eXnwjyJaX72cVRmb"
        }
      ],
      "steps": [
        "lsxj_K_Cu-dTOXeMy6N1r",
        "-Uum_WruYDefivd3iTC_A",
        "UcV8YBrF9SgI13fZZu7S7",
        "ln6JCUpOIIy2dddDv6ZcI",
        "j7l8s3g8wEp7s3PUW2v-q"
      ],
      "title": "Second Test"
    },
    {
      "id": "_87hP9cL5MUJP_j1POR4b",
      "type": "SECTION",
      "items": [],
      "steps": [],
      "title": ""
    }
  ]
}
  1. How do I extract all the steps (only steps) from the above JSON ?
  2. How do I extract all the steps and their group ID's and section ID's using postgres query?

I have used recursive CTE's so far, but I'm getting either one of these errors, "could not identify an equality operator for type json" or "ERROR: set-returning functions are not allowed in CASE". I have even changed column type from json to jsonb and viceversa.

Here's what I have used so far,

WITH RECURSIVE procedures (json_element) AS (
  -- non recursive term
  SELECT
    column_i_want
  FROM from_table WHERE system_id = 'abc'
 
  UNION
 
  -- recursive term
  SELECT
    CASE
    WHEN jsonb_typeof(json_element) = 'array' OR jsonb_typeof(json_element) = 'object'
      THEN jsonb_array_elements_text(json_element)
    WHEN jsonb_exists(json_element, 'steps')
      THEN jsonb_array_elements_text(json_element -> 'steps')
    END AS json_element
  FROM
    procedures
  WHERE
    jsonb_typeof(json_element) = 'array' OR jsonb_typeof(json_element) = 'object'
)

SELECT * FROM procedures;

I'm using Aurora Serverless with version (psql (13.3, server 12.8))

Any help is greatly appreciated..! Thanks.

0 Answers
Related