转换 PostgreSQL JSONB 列结果以在条件中使用 IN

Convert PostgreSQL JSONB column results for use in condition with IN

我有一个 table 和一个 JSONB 列,用于存储已应用于任务的多个标签(整数),例如:'[123, 456, 789]'.

ALTER TABLE "public"."task" ADD COLUMN "tags" jsonb;

我还有一个table专门用来存放所有可以使用的标签,每条记录的主键都用在我任务的JSONB列table.

CREATE TABLE public.tag (
    tag_id serial NOT NULL,
    label varchar(50) NOT NULL,
);

在这个 table(标签)中,我有一个基于任务 ID 的索引,我想在查询中使用这个索引,returns 任务中使用的标签标签.

SELECT * FROM task, tag WHERE task.tags @> to_jsonb(tag.tag_id)

使用 to_jsonb 真的很糟糕,因为它不使用我的 table 的索引,但是如果我将 SQL 更改为类似于下面的示例,索引是使用和 SQL 性能要好得多。

SELECT * FROM tag WHERE tag.tag_id IN (123, 456, 789)

如何将jsonb列(任务table)转换为一组可以与IN条件一起使用的整数值,如下例所示?

SELECT * FROM task, tag WHERE tag.tag_id IN (task.tags);

您可以使用 PostgreSQL jsonb_array_elements 函数将 JSON 元素转换为 table 记录。例如:

SELECT * FROM task, tag WHERE tag.tag_id in (
    select jsonb_array_elements('[200, 100, 789]'::jsonb)::int4 as json_data
);

但是,为了获得最佳性能,如果您从 table 字段中获取 JSON 数据,那么您必须索引此 JSON 字段而不是使用标准 btree 索引类型。对于 JSON 类型,PostgreSQL 具有与 GIN 索引不同的索引类型。此索引类型将提供最佳性能。我在我的 table 中使用了这个索引,它有一百万条记录。非常非常好的表现。创建 GIN 索引的示例:

CREATE INDEX tag_table_json_index ON tag_table USING gin (json_field_name jsonb_path_ops);