Collect Recursive JSON Keys In Postgres

前端 未结 3 1047
借酒劲吻你
借酒劲吻你 2020-12-03 08:59

I have JSON documents stored in Postgres under the JSON data type (Postgres 9.3) and I need to recursively collect the key names down the tree.

For example, given th

3条回答
  •  Happy的楠姐
    2020-12-03 09:34

    The trick is to add some final condition testing using json_typeof at the right place.

    You should also be using jsonb if you don't care about object key order.

    Here is my working environment:

    CREATE TABLE test (
      id  SERIAL PRIMARY KEY,
      doc JSON
    );
    
    INSERT INTO test (doc) VALUES ('{
     "files": {
      "folder": {
       "file1": {
        "property": "blah"
       },
       "file2": {
        "property": "blah"
       },
       "file3": {
        "property": "blah"
       },
       "file4": {
        "property": "blah",
        "prop" : {
          "clap": "clap"
        }
       }
     }
    },
    "software": {
      "apt": {
        "package1": {
            "version": 1.2
        },
        "package2": {
            "version": 1.2
        },
        "package3": {
            "version": 1.2
        },
        "package4": {
            "version": 1.2
        }
      }
     }
    }');
    

    The recursion is stopped when the second query does not return any rows. This is done by passing an empty object to json_each.

     WITH RECURSIVE doc_key_and_value_recursive(key, value) AS (
      SELECT
        t.key,
        t.value
      FROM test, json_each(test.doc) AS t
    
      UNION ALL
    
      SELECT
        t.key,
        t.value
      FROM doc_key_and_value_recursive,
        json_each(CASE 
          WHEN json_typeof(doc_key_and_value_recursive.value) <> 'object' THEN '{}' :: JSON
          ELSE doc_key_and_value_recursive.value
        END) AS t
    )
    SELECT *
    FROM doc_key_and_value_recursive
    WHERE json_typeof(doc_key_and_value_recursive.value) <> 'object';
    

提交回复
热议问题