如何在PostgreSQL 9.3中索引JSON数据,当它的密钥未知时?

时间:2014-02-11 07:58:53

标签: json indexing postgresql-9.3

有谁知道如何在PostgreSQL 9.3中为以下JSON数据创建索引?

示例数据:

{
  {"1111" : "aaaa"},
  {"2222" : "bbbb"},
  {"3333" : "cccc"}
}

如果我想在所有密钥上编制索引怎么做?

感谢。

1 个答案:

答案 0 :(得分:1)

你还没有明确定义你想要的东西;这就是我所说的你的意思:

  

创建一个索引,让我测试任何给定的json值(上面的例子)是否包含名为'k'的键

我认为如果json结构是统一的,那么在9.3中这是可能的(理智),即你总是有一个扁平物体阵列。如果是这种情况,您可以提取一系列密钥,例如

regress=> create table x as select '[
  {"1111" : "aaaa"},
  {"2222" : "bbbb"},
  {"3333" : "cccc"}
]'::json as col;
SELECT 1

regress=> select array_agg(k) from x, lateral json_array_elements(col) e, lateral json_object_keys(e) k;
    array_agg     
------------------
 {1111,2222,3333}
(1 row)

并将其包装在SQL函数中:

CREATE OR REPLACE FUNCTION json_array_object_keys(json) RETURNS text[] AS $$
select array_agg(k) FROM lateral json_array_elements($1) e, lateral json_object_keys(e) k;
$$ LANGUAGE sql IMMUTABLE;

的工作原理如下:

craig=> SELECT json_array_object_keys(col) from x;
 json_array_object_keys 
------------------------
 {1111,2222,3333}
(1 row)

然后在表达式上创建一个GIN数组索引:

CREATE INDEX json_nested_keys_idx ON x USING GIN( json_array_object_keys(col) );

(警告,这样的索引更新会很慢,会减慢插入/更新/删除的速度)

并按如下方式使用:

SELECT * FROM x WHERE json_array_object_keys(col) @> ARRAY['1111'];

您不能使用数组方法对LIKE进行索引搜索;你必须将数组压缩成文本文字:

CREATE OR REPLACE FUNCTION json_array_object_keys_delim(json) RETURNS text AS $$
select array_to_string(array_agg(k),'|') FROM lateral json_array_elements($1) e, lateral json_object_keys(e) k;
$$ LANGUAGE sql IMMUTABLE;

CREATE INDEX json_tgrm_keys_idx ON x USING GiST( (json_array_object_keys_delim(col)) gist_trgm_ops);

SELECT * FROM x WHERE json_array_object_keys_delim(col) LIKE '%111%';