在 PostgreSQL GIN 索引中使用 JSON 个对象值
Using JSON object values in PostgreSQL GIN index
我想为我的 JSONB 对象 obj
中的所有值创建一个 trgm GIN 索引 obj
。
我想出的第一个方法是这样的:
CREATE INDEX table_values_idx ON table
USING GIN (array_to_string(
(SELECT value FROM jsonb_each_text(obj)), ' ') gin_trgm_ops);
当然上面的不行,因为子查询(SELECT
)不能在PostgreSQL索引中使用。
是否有另一种方法可以在不使用子查询的情况下连接 JSONB 对象的值?
您需要为此定义您的自定义函数,因为内置 json[b]
函数全部 return setof sometype
.
create or replace function jsonb_values(jsonb)
returns text array
language sql
immutable
as $func$
select case jsonb_typeof()
when 'null' then array[]::text[]
when 'object' then array(select v from jsonb_each() e, unnest(jsonb_values(e.value)) v)
when 'array' then array(select v from jsonb_array_elements() e, unnest(jsonb_values(e)) v)
else array(select v from jsonb_build_array() a, jsonb_array_elements_text(a) v)
end
$func$;
http://rextester.com/GSTHZ3132
有了这个,您可以创建一个索引,例如:
CREATE INDEX table_values_idx ON table
USING GIN (array_to_string(jsonb_values(obj), ' ') gin_trgm_ops);
之后,您可以将此索引用于 LIKE
和 FTS 查询:
select *
from table
where array_to_string(jsonb_values(obj), ' ') like '%abc%'
我想为我的 JSONB 对象 obj
中的所有值创建一个 trgm GIN 索引 obj
。
我想出的第一个方法是这样的:
CREATE INDEX table_values_idx ON table
USING GIN (array_to_string(
(SELECT value FROM jsonb_each_text(obj)), ' ') gin_trgm_ops);
当然上面的不行,因为子查询(SELECT
)不能在PostgreSQL索引中使用。
是否有另一种方法可以在不使用子查询的情况下连接 JSONB 对象的值?
您需要为此定义您的自定义函数,因为内置 json[b]
函数全部 return setof sometype
.
create or replace function jsonb_values(jsonb)
returns text array
language sql
immutable
as $func$
select case jsonb_typeof()
when 'null' then array[]::text[]
when 'object' then array(select v from jsonb_each() e, unnest(jsonb_values(e.value)) v)
when 'array' then array(select v from jsonb_array_elements() e, unnest(jsonb_values(e)) v)
else array(select v from jsonb_build_array() a, jsonb_array_elements_text(a) v)
end
$func$;
http://rextester.com/GSTHZ3132
有了这个,您可以创建一个索引,例如:
CREATE INDEX table_values_idx ON table
USING GIN (array_to_string(jsonb_values(obj), ' ') gin_trgm_ops);
之后,您可以将此索引用于 LIKE
和 FTS 查询:
select *
from table
where array_to_string(jsonb_values(obj), ' ') like '%abc%'