如何从 PostgreSQL 中的 jsonb 数组中获取特定对象?

Rab*_*hah 21 postgresql array json postgresql-9.4

我有一个名为“user”的字段,其中包含一个大致如下所示的 json 数组:

"user"

[{ "_id" : "1", "count" : "4" }, { "_id" : "3", "count": "4"}]
Run Code Online (Sandbox Code Playgroud)

现在我想要一个像这样的查询:

select count from tablename where id = "1"
Run Code Online (Sandbox Code Playgroud)

我无法count从 PostgreSQL 9.4 中的 json 对象数组中获取特定字段。

Erw*_*ter 26

将您的值存储在规范化模式中会更有效率。也就是说,您也可以使其与您当前的设置一起使用。

假设

假设这个表定义:

CREATE TABLE tbl (tbl_id int, usr jsonb);
Run Code Online (Sandbox Code Playgroud)

“user”是一个保留字,需要双引号作为列名。不要那样做。我用usr代替。

询问

该查询并不像(现已删除)评论那样微不足道:

SELECT t.tbl_id, obj.val->>'count' AS count
FROM   tbl t
JOIN   LATERAL jsonb_array_elements(t.usr) obj(val) ON obj.val->>'_id' = '1'
WHERE  t.usr @> '[{"_id":"1"}]';
Run Code Online (Sandbox Code Playgroud)

3个基本步骤

1. 廉价地识别符合条件的行

WHERE t.usr @> '[{"_id":"1"}]'标识 JSON 数组中具有匹配对象的行。该表达式可以在jsonb列上使用通用 GIN 索引,或者使用更专业的运算符类jsonb_path_ops

CREATE INDEX tbl_usr_gin_idx ON tbl USING gin (usr jsonb_path_ops);
Run Code Online (Sandbox Code Playgroud)

添加的WHERE子句在逻辑上多余的,但需要使用索引。join 子句中的表达式强制执行相同的条件,但仅到目前为止符合条件的每一行中取消嵌套数组之后。有了索引支持,Postgres 只处理包含合格对象的行。与小表无关紧要,但与大表和只有少数符合条件的行有很大不同。

有关的:

2. 识别数组中的匹配对象

取消嵌套jsonb_array_elements()。(unnest()仅适用于 Postgres 数组类型。)因为我们只对实际匹配的对象感兴趣,所以立即过滤连接条件。

有关的:

3. 为嵌套键提取值 'count'

后符合条件的对象已被提取,简单地说:obj.val->>'count'

  • `obj(value)` 是从哪里来的?它是在`LATERAL JOIN`、`jsonb_array_elements` 还是其他地方? (2认同)

归档时间:

查看次数:

68764 次

最近记录:

6 年,4 月 前