使用 PostgreSQL 查询哈希的嵌套哈希

Querying nested hash of hashes using PostgreSQL

我有一个 json 数据类型字段来存储复杂数据。 JSON 数据看起来像这样的散列:

{
  "0" => {
    "origin" => {},
    "diff" => {
      "type" => "type_1",
      ...
    }
  },
  "1" => {
    "origin" => {
      "type" => "type_2",
      ...
    },
    "diff" => {
      ...
    }
  },
  ...
}

我试图将 json 转换为数组以避免这些索引键,但它对我没有帮助。

WITH data_values AS (
  SELECT id, array_to_json(array(SELECT t.v from json_each_text(data) as t(k,v))) as array_data
  FROM event_logs
)
SELECT * FROM data_values
WHERE array_data->'origin'->>'type' = 'type_3' OR array_data->'diff'->>'type' = 'type_3'

此外,我有一个想法使用 json_object_keys 并遍历顶级键以找到必要的 key/value 对,但我是 PSQL 的新手并且我有一些问题解决那个问题。

PSQL 的版本是 11,所以 JSON 路径对我来说不可用。

Table定义示例:

CREATE TABLE event_logs (
    id integer,
    data json,
    created_at timestamp without time zone
);

INSERT INTO event_logs (id, data)
VALUES 
  (1, '{"0": {"origin": {}, "diff": {"type": "type_1"}}, "1": {"origin": {"type": "type_1"}, "diff": {}}}'),
  (2, '{"0": {"origin": {}, "diff": {"type": "type_2"}}, "1": {"origin": {}, "diff": {"type": "type_3"}}}'),
  (3, '{"0": {"origin": {}, "diff": {"type": "type_3"}}, "1": {"origin": {"type": "type_2"}, "diff": {}}}')

重要说明:顶级键的数量可能不同。

我想按 key/value 对查找记录(例如,type = 'type_3')。它应该 select ID 为 2 和 3 的记录。

你能帮我做对吗?

将对象存储为数组而不是整数索引对象是个好主意,但这不会让您使用 -> 运算符跳过此级别。 (只有 jsonpath 可以做到这一点)。

您需要在 WHERE 子句中使用 json_each 迭代:

SELECT * FROM data_values
WHERE EXISTS(
  SELECT *
  FROM json_each(data)
  WHERE value->'origin'->>'type' = 'type_3'
     OR value->'diff'->>'type' = 'type_3'
);

(如果您使用数组,json_each 将变为 json_array_elements)。