在PostgreSQL GIN索引中使用JSON对象值

在PostgreSQL GIN索引中使用JSON对象值,postgresql,plpgsql,indices,Postgresql,Plpgsql,Indices,我想为我的JSONB对象中的所有值创建一个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索引中使用 有没有其他方法不使用子查询就连接J

我想为我的JSONB对象中的所有值创建一个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]
函数都返回
sometype集

create or replace function jsonb_values(jsonb)
  returns text array
  language sql
  immutable
as $func$
  select case jsonb_typeof($1)
    when 'null'   then array[]::text[]
    when 'object' then array(select v from jsonb_each($1) e, unnest(jsonb_values(e.value)) v)
    when 'array'  then array(select v from jsonb_array_elements($1) e, unnest(jsonb_values(e)) v)
    else array(select v from jsonb_build_array($1) a, jsonb_array_elements_text(a) v)
  end
$func$;

使用此选项,您可以创建一个索引,如:

CREATE INDEX table_values_idx ON table
  USING GIN (array_to_string(jsonb_values(obj), ' ') gin_trgm_ops);
之后,您可以将此索引用于
和FTS查询:

select *
from   table
where  array_to_string(jsonb_values(obj), ' ') like '%abc%'

谢谢,尽管这看起来像是作弊,因为SELECT也出现在函数中;-)我采用了您的解决方案的一个变体,它似乎有效。@lue3Seba不幸的是,如果函数中没有
SELECT
,它就无法解决。此变体还处理内部数组和对象,但如果不需要,请确保可以简化它。我只是试着想想任何可能性。