如何在postgres中的json数组上创建索引?

时间:2019-01-01 04:51:57

标签: postgresql postgresql-9.5

我的表演示中有一个名为“ elements”的json字段,其中包含一个包含键值对的数组“ data”。 “数据”数组具有以下结构。数据数组可能有多个json条目。我使用的是Postgres 9.5版

{
    "data": [{
        "ownr": "1",
        "sigUsr": [2],
        "sigStat": "APPR",
        "modifiedOn": 1494229698039,
        "isDel": "false",
        "parentId": "nil",
        "disName": "exmp.json",
        "uniqueId": "d88cb52",
        "usrType": "owner",
        "usrId": "1",
        "createdOn": 1494229698039,
        "obType": "file"
    }]
}

在我的查询中,我有多个基于obj的过滤器(例如obj->>usrIdobj->>sigUsr等),其中obj对应于json_array_elements(demo.elements->'data')。如何在{{ 1}},obj->>userId?请还原。

问候 sur

1 个答案:

答案 0 :(得分:0)

首先,如果列数据类型是JSON而不是JSONB,则只能创建索引 在整个demo.elements列上。只有JSONB列可以在json键上具有索引。

如果在此表中指定JSON,则可以考虑更改数据类型。

然后,我将您的情况修改为以下测试用例。

create table demo(
elements jsonb
);
insert into demo values(
'{
    "data": [
        {
            "ownr": "1",
            "sigUsr": [
                2
            ],
            "sigStat": "APPR",
            "modifiedOn": 1494229698039,
            "isDel": "false",
            "parentId": "nil",
            "disName": "exmp.json",
            "uniqueId": "d88cb52",
            "usrType": "owner",
            "usrId": "1",
            "createdOn": 1494229698039,
            "obType": "file"
        }
    ]
}'
);

您所询问的查询可以通过我能想到的以下方式来实现。

postgres=# -- First possible query
postgres=# select elements->'data'->0->'usrId', elements->'data'->0->'sigUsr' from demo;
 ?column? | ?column? 
----------+----------
 "1"      | [2]
(1 row)

postgres=# -- Second possible query, with jsonb_array_elements()
postgres=# select obj->>'usrId', obj->>'sigUsr' from demo d,  jsonb_array_elements(d.elements->'data') as obj;
 ?column? | ?column? 
----------+----------
 1        | [2]
(1 row)

postgres=# 

我只能使用第一个索引创建索引,这是一个限制性用例。您需要在索引中写入特定的数组条目(在本例中为第0个元素)。

postgres=# create index ON demo ((elements->'data'->0->'usrId'));
CREATE INDEX
postgres=# 

由于jsonb_array_elements()返回setof jsonb类型,因此我无法为第二种方法创建索引。

postgres=# create index ON demo ((jsonb_array_elements(elements->'data')->>'usrId'));
ERROR:  set-returning functions are not allowed in index expressions
LINE 1: create index ON demo ((jsonb_array_elements(elements->'data'...
                               ^
postgres=# 

我认为您应该将sub-json条目存储在单独的行中,而不是将它们存储在json数组中。