Postgres 9.5 - 查询嵌套 JSON 元素的数组长度
Posted
技术标签:
【中文标题】Postgres 9.5 - 查询嵌套 JSON 元素的数组长度【英文标题】:Postgres 9.5 - Querying array length of a nested JSON element 【发布时间】:2017-04-26 10:23:07 【问题描述】:我有一个包含 JSON 字段的 Postgres 表,该字段标识与给定记录关联的图像。该字段的内容如下所示:
"photo-verification":
"photos": [
"type": "photo-verification", "fileName": "4f35a880-e9a0-43f9-a31e-1bb8b765d04d", "mimeType": "image/jpeg", "createdBy": "jmlittm", "createdTs": "2016-06-20T20:25:39.706Z", "delFlag": false, "updatedBy": "jmlittm", "updatedTs": "2016-06-20T20:25:39.706Z",
"type": "photo-verification", "fileName": "3a104d07-dc48-4f59-b83f-06cd35a21dae", "mimeType": "image/jpeg", "createdBy": "jmlittm", "createdTs": "2016-06-20T22:31:09.808Z", "delFlag": false, "updatedBy": "jmlittm", "updatedTs": "2016-06-20T22:31:09.808Z"
]
一条记录可以有 0 个或多个关联图像 - 如果没有图像,则整个字段将为空。我正在尝试编写一个查询来确定与给定记录关联的图像数量。最终结果应该是计算有多少条记录有一张图像,有多少条记录有不止一张。如果我查询 JSON 的顶层,如下所示:
select n.images->'photo-verification' from notes n;
我可以获得包含照片数组的内部 JSON,但如果我尝试更深入地挖掘,我不会得到任何结果。我的想法是我可以做一些类似的事情
select array_length(n.images->'photo-verification'->'photos', 1) from notes n;
或
select json_array_length(n.images->'photo-verification'->'photos') from notes n;
但我最终得到了错误和提示,也许我应该考虑强制转换。
我刚刚开始深入研究 Postgres,所以我仍在尝试围绕查询语言的一些更精细的点展开思考。我将继续研究,但如果有人提供任何帮助或见解,我将不胜感激。
编辑:
所以,我认为我可以通过创建一个仅包含“照片”JSON 并过滤掉所有空字段的视图来简化问题:
CREATE VIEW photos as SELECT n.images->'photo-verification' as photo FROM notes.notes n where (n.images->'photo-verification')::text != '';
它起作用了,因为我现在有一个带有 JSON 列的视图,如下所示:
"photos": [
"type": "photo-verification", "fileName": "4f35a880-e9a0-43f9-a31e-1bb8b765d04d", "mimeType": "image/jpeg", "createdBy": "jmlittm", "createdTs": "2016-06-20T20:25:39.706Z", "delFlag": false, "updatedBy": "jmlittm", "updatedTs": "2016-06-20T20:25:39.706Z",
"type": "photo-verification", "fileName": "3a104d07-dc48-4f59-b83f-06cd35a21dae", "mimeType": "image/jpeg", "createdBy": "jmlittm", "createdTs": "2016-06-20T22:31:09.808Z", "delFlag": false, "updatedBy": "jmlittm", "updatedTs": "2016-06-20T22:31:09.808Z"
]
但是,如果我尝试
select json_array_length(photo) from photos;
我明白了:
ERROR: cannot get array length of a scalar
如果我尝试
select json_array_length(photo->'photos') from photos;
我得到一堆空白记录。
我一定是错过了什么……
【问题讨论】:
【参考方案1】:create temp table t (id int, data json);
insert into t values
(1,
'"photo-verification":
"photos": [
"type": "photo-verification", "fileName": "4f35a880-e9a0-43f9-a31e-1bb8b765d04d", "mimeType": "image/jpeg", "createdBy": "jmlittm", "createdTs": "2016-06-20T20:25:39.706Z", "delFlag": false, "updatedBy": "jmlittm", "updatedTs": "2016-06-20T20:25:39.706Z",
"type": "photo-verification", "fileName": "3a104d07-dc48-4f59-b83f-06cd35a21dae", "mimeType": "image/jpeg", "createdBy": "jmlittm", "createdTs": "2016-06-20T22:31:09.808Z", "delFlag": false, "updatedBy": "jmlittm", "updatedTs": "2016-06-20T22:31:09.808Z"
]
'),
(2,
'"photo-verification":
"photos": [
"type": "photo-verification", "fileName": "4f35a880-e9a0-43f9-a31e-1bb8b765d04d", "mimeType": "image/jpeg", "createdBy": "jmlittm", "createdTs": "2016-06-20T20:25:39.706Z", "delFlag": false, "updatedBy": "jmlittm", "updatedTs": "2016-06-20T20:25:39.706Z"
]
')
;
select id, json_array_length(data->'photo-verification'->'photos')
from t;
或者,如果您对某个特定领域感兴趣:
select json_array_elements(data->'photo-verification'->'photos')->>'fileName' as fileName
from t;
【讨论】:
谢谢,mcNets - 这正是我正在寻找的。有趣的是,如果我直接从表中运行该查询 -select id, json_array_length(images->'photo-verification'->'photos') from notes.notes where images::text != '';
,我会得到所有的 ID,但长度字段是空的。我正在使用外部数据包装器,但数据通过时看起来仍然没问题。也许如果我做了一个 SELECT INTO,并将它放在一个临时表中,我可能会有更好的运气。 【参考方案2】:
似乎需要转换为 JSON:
select json_array_length((images->'photo-verification'->'photos')::json)
from notes;
【讨论】:
好吧,我尝试了select count(*) from notes where json_array_length((images->'photo-verification'->'photos')::json) > 1;
,结果返回计数为零。不过,这似乎是正确的轨道。感谢收看!以上是关于Postgres 9.5 - 查询嵌套 JSON 元素的数组长度的主要内容,如果未能解决你的问题,请参考以下文章
在postgres 9.5中插入包含json对象的数组作为行
Postgres:使用 django 对 json 键进行值查询
RDS postgres 从 9.4 升级到 9.5,CPU 卡在 100% 几个小时