我有一个带有示例内容的jsonb列,如下所示:
{"kay1": val1, "myMap": {"UniqueKey1": "UniqueValue1", "UniqueKey2": "UniqueValue2", "UniqueKey3": "UniqueValue3", "UniqueKey4": "UniqueValue4"}, "key2": {"key3": {"key4": "val4"}, "val3": {"key5": "val5"}}
我想找到'myMap'中的条目数大于/等于/小于某个整数的所有行 - 我有几百万这样的行,所以如果也可以使用索引,这将是有帮助的!
在上面的示例中,'myMap'中有4个条目。因此,对于查询类似“select * from myTable,其中jsonb_key_length(myJsonbColumn - >'myMap')= 4”,应返回上面的行。 [假设有一个函数jsonb_key_length()返回给定json对象的长度]
我在这里找到了类似的问题:Postgres json key count。
但是,它需要键的名称,这可以在不使用键名的情况下完成吗?
解决方案
感谢@jmelesky提出的建议。
以下查询为我工作:
SELECT id, count(elements)
FROM (SELECT id, jsonb_object_keys(column -> 'myMap') AS elements
FROM myTable GROUP BY id
) x
GROUP BY id
包括@ jmelesky的建议
SELECT id, (SELECT count(*)
FROM (SELECT jsonb_object_keys(a->'myMap')
FROM test_json x where x.id = y.id
) z
) count
FROM test_json y group by id;
找到另一个更快的解决方案
SELECT id, ARRAY_LENGTH(ARRAY(SELECT jsonb_object_keys(column -> 'myMap')), 1) AS count
FROM myTable
使用索引:
创建一个函数:
CREATE OR REPLACE FUNCTION jsonb_object_keys_length(_j jsonb)
RETURNS INT LANGUAGE SQL IMMUTABLE AS
'SELECT ARRAY_LENGTH(ARRAY(SELECT jsonb_object_keys(column -> 'myMap')), 1)';
创建索引:
CREATE INDEX idx_myMapCount ON myTable (jsonb_object_keys_length(column -> 'myMap'));
在查询中使用函数:
SELECT id, jsonb_object_keys_length(column -> 'myMap') AS count
FROM myTable
如果有更好的方法来建模此查询,请建议。谢谢!
答案 0 :(得分:4)
function名为json_object_keys
,这可能是此问题的关键部分。它接受一个json对象并将键作为关系的行返回。
=# create table test_json (a json);
CREATE TABLE
=# insert into test_json values ('{"kay1": 1, "myMap": {"UniqueKey1": "UniqueValue1", "UniqueKey2": "UniqueValue2", "UniqueKey3": "UniqueValue3", "UniqueKey4": "UniqueValue4"}, "key2": {"key3": {"key4": "val4"}, "val3": {"key5": "val5"}}}');
INSERT 0 1
=# select json_object_keys(a) from test_json;
json_object_keys
------------------
kay1
myMap
key2
(3 rows)
=# select json_object_keys(a->'myMap') from test_json;
json_object_keys
------------------
UniqueKey1
UniqueKey2
UniqueKey3
UniqueKey4
(4 rows)
从那里,您可以将其包装在子查询中,如下所示:
=# select count(*) from (select json_object_keys(a->'myMap') from test_json) x;
count
-------
4
(1 row)
编辑添加:有一个jsonb等效项(jsonb_object_keys
),与jsonb值的工作方式相同。对不起,我倾向于用vanilla json做我的测试用例。