有谁知道如何在PostgreSQL 9.3中为以下JSON数据创建索引?
示例数据:
{
{"1111" : "aaaa"},
{"2222" : "bbbb"},
{"3333" : "cccc"}
}
如果我想在所有密钥上编制索引怎么做?
感谢。
答案 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%';