0

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

示例数据:

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

说如果我想索引所有键怎么做?

谢谢。

4

1 回答 1

1

你没有明确定义你想要什么;这就是我假设你的意思:

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

我认为这只有在 9.3 中才有可能(理智地)如果 json 结构是统一的,即你总是有一个平面对象数组。如果是这种情况,您可以提取一个键数组,例如

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%';
于 2014-02-13T00:07:49.450 回答