当前位置: 首页 > 面试题库 >

在Postgres中收集递归JSON键

陈开宇
2023-03-14
问题内容

我在JSON数据类型(Postgres 9.3)下以Postgres存储了JSON文档,我需要递归地收集树下的键名。

例如,给定此JSON树

{
 "files": {
  "folder": {
   "file1": {
    "property": "blah"
   },
   "file2": {
    "property": "blah"
   },
   "file3": {
    "property": "blah"
   },
   "file4": {
    "property": "blah"
   }
 }
},
"software": {
  "apt": {
    "package1": {
        "version": 1.2
    },
    "package2": {
        "version": 1.2
    },
    "package3": {
        "version": 1.2
    },
    "package4": {
        "version": 1.2
    }
  }
 }
}

我想提取类似[file1,file2,file3,file3,package1,package2,package3,package4]的内容

基本上只列出了可用于文本搜索索引的键。

我知道我可以使用以下方法在最外面的对象上列出键

SELECT DISTINCT(json_object_keys(data))

而且我知道可以使用类似的方法递归爬过树

WITH RECURSIVE data()

但是我很难将两者放在一起。

有人可以帮忙吗?


问题答案:

诀窍是json_typeof在正确的位置添加一些最终条件测试。

jsonb如果您不关心对象键顺序,也应该使用。

这是我的工作环境:

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
    }
  }
 }
}');

当第二个查询不返回任何行时,递归将停止。这是通过将空对象传递到来完成的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';


 类似资料:
  • 问题内容: 我期望以下内容返回所有元组,将层次结构中的每个父级解析到顶部,但它仅返回最低级别(在查询中指定了其ID)。如何为给定的level_id返回整棵树? 问题答案: 首先,如果您确实是祖父母,则应该如此。其次,您在查询的递归一半中的(隐式)连接条件是向后的,您想让父级脱离,而不是:

  • 我在Postgres数据库中有一个分层表,例如,

  • 我有以下代码,即从返回CompletableFuture的web API获取给定时间间隔的报告。如果超过了返回报告的行数,时间间隔将被分成两半,并为两半调用API。这将递归重复,直到行数满足条件。 我想得到完全未来 我的代码在不需要进行间隔拆分时运行正常。如果需要递归调用,它将只返回空列表,递归调用将在稍后异步执行。 我也尝试过使用类似的东西,但没用: 如果我知道自己做错了什么,我会心存感激。谢谢

  • 问题内容: 有什么方法可以混合使用递归和语句吗?例如,无限数生成器(使用递归)将类似于: 我试过了: 和 但是他们都没有做我想要的事情,第一个在屈服后停止,第二个在屈服之后,然后是发电机,然后停了下来。 注意: 请知道,您可以使用while循环来做到这一点: 我只想知道这是否可以递归进行。 问题答案: 是的,您可以这样做: 但是,一旦达到最大递归深度,这将出错。 从Python 3.3开始,您将可

  • 可以在getData()方法中多次调用QueryList来实现递归多级采集。 使用场景:如采集多级菜单,需要先采集第一级菜单,然后采集第二级菜单,以此类推。 示例采集代码: <?php require 'QueryList/vendor/autoload.php'; use QL\QueryList; //获取每个li里面的h3标签内容,和class为item的元素内容 $html =<<<S

  • 我必须使用递归帮助方法来解决这个问题,而我完全是空白的 这是我目前所掌握的 尝试在建议后编辑: