在 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%'