搜索并提取位于 json 结构的各种路径中的元素

Search and extract element located in various path of json structure

我在 PostgreSQL 数据库中有一个 json,我需要提取一个并不总是位于同一位置的数组。

Problem

Rules

JSON structure

pages : [
  {
    name : 'page1',
    elements : [
      { name : 'element1', choicies : [...]},
      { name : 'element2', choicies : [...]}
    ]
  }, {
    name : 'page2',
    elements : [
      {
        name : 'element3',
        templateElements : [
          {
            name : 'element4'
            choicies : [...]
          }, {                  
            name : 'element5'
            choicies : [...]
          }
       ]
      }, {
        name : 'element6'
        choicies : [...]
      }
    ]
  },{
    name : 'element7',
    templateElements : [
      {
        name : 'element8'
        choicies : [...]
      }
    ]
  }         
]

我尝试通过展平结构来提取元素

SELECT  pages::jsonb->>'name',
        pageElements::jsonb ->> 'name',
        pageElements::jsonb -> 'choicies',
        pages.*
FROM    myTable as myt,
        jsonb_array_elements(myt.json -> 'pages') as pages,
        jsonb_array_elements(pages -> 'elements') as pageElements

唉,列 choicies 在我的结果中总是空的。当元素位于其他地方时,这将不起作用,比如

我不知道是否有办法在 json 结构中的任何位置搜索键(名称)并提取另一个键(选项)。

我想调用一个 select 参数 return 选择此元素的元素名称。

例如,如果我用元素名称(element1 或 element4 或 element8)调用 select,则此元素的选择数组(作为行或 json 或文本,此处没有偏好)应该是return.

哇!解决方案成立属于期待! JSONPath 是必经之路

我们可以用它做些什么。

SQL

-- Use jsonpath to search, filter and return what's needed
SELECT  jsonb_path_query(
            myt.jsonb,
            '$.** ? (@.name == "element_name_to_look_at")'
        )->'choices' as jsonbChoices
FROM    myTable as myt

Explanation of jsonpath in SQL

jsonb_path_query(jsonb_data, '$.** ? (@.name == "element_name_to_look_at")')->'choices'
  • jsonb_path_query : posgresql jsonpath 函数
  • jsonb_data : 带有 jsonb 数据或 jsonb 表达式的数据库列
  • $.** : 从根元素开始到处搜索
  • ? : where 子句/过滤器
  • @ : 对象 return 通过搜索
  • @.name == "element_name_to_look_at" :每个对象 name 等于 element_name_to_look_at
  • ->'choices' :对于每个由 jsonpath 编辑的对象 return,获取 choices 属性

Final version

得到 choices jsonb 数组后,我们 return 一个包含各种选择的数据集。

choices 数组如下所示:

[{value:'code1',text:'Code Label 1'}, {value:'code2',text:'Code Label 2'},...]

SELECT  choices.*
FROM    (
        -- Use jsonpath to search, filter and return what's needed
        SELECT  jsonb_path_query(myt.jsonb, '$.** ? (@.name == "element_name_to_look_at")')->'choices' as jsonbChoices
        FROM    myTable as myt
) choice,
-- Explode json return array into columns
jsonb_to_recordset(choice.jsonbChoices) as choices(value text, text text);