Postgres | Создать частичный индекс GIN с несколькими частичными параметрами, включенными в индекс

#postgresql

#postgresql

Вопрос:

Вопрос касается построения частичных индексов GIN.

У меня есть следующая таблица.

 -- auto-generated definition
create table archives_subtitles
(
    id             serial     not null
        constraint archives_subtitles_pkey
            primary key,

    episode_number smallint   not null
        constraint archives_subtitles_episode_number_check
            check (episode_number >= 0),

    text           text       not null,

    language       varchar(2) not null

    season_id      integer    not null
        constraint archives_subtitles_season_id_e3690b93_fk_archives_
            references archives_seasonmodel
            deferrable initially deferred,
    constraint archives_subtitles_season_id_episode_number_fec69da8_uniq
        unique (season_id, episode_number, language)
);



  

Я хочу создать частичный GIN индекс для FTS , подобный этому:

 CREATE INDEX CONCURRENTLY IF NOT EXISTS test ON archives_subtitles
    USING GIN
    (to_tsvector('english', text))
    WITH (fastupdate = off)
    WHERE language = 'en'
;

  

Проблема в том, что мне нужно указать несколько десятков языков в to_tsvector и в WHERE language = 'language_code'

Возможно ли каким-то образом включить несколько параметров с несколькими разными (to_tsvector('language_name', text)) / WHERE language = 'language_code' парами внутри определения индекса вместо того, чтобы вручную повторять подобное:

 CREATE INDEX CONCURRENTLY IF NOT EXISTS test1 ON archives_subtitles
    USING GIN
    (to_tsvector('english', text))
    WITH (fastupdate = off)
    WHERE language = 'en'
;
CREATE INDEX CONCURRENTLY IF NOT EXISTS test2 ON archives_subtitles
    USING GIN
    (to_tsvector('french', text))
    WITH (fastupdate = off)
    WHERE language = 'fr'
;
CREATE INDEX CONCURRENTLY IF NOT EXISTS test3 ON archives_subtitles
    USING GIN
    (to_tsvector('russian', text))
    WITH (fastupdate = off)
    WHERE language = 'ru'
;
etc
etc
etc
…
  

Спасибо.

Ответ №1:

Создайте простую IMMUTABLE функцию, подобную этой:

 CREATE FUNCTION lang_to_tsconfig(text) RETURNS regconfig
   LANGUAGE sql IMMUTABLE STRICT AS
$$SELECT CASE WHEN $1 = 'en' THEN 'english'::regconfig
              WHEN $1 = 'de' THEN 'german'::regconfig
              ...
         END$$;
  

и создайте свой индекс, подобный:

 CREATE INDEX ON archives_subtitles USING gin (
   to_tsvector(lang_to_tsconfig(language), text))
   WITH (fastupdate = off);
  

Ответ №2:

ответ @Laurenz Albe сработал для меня, как и в следующей реализации кода. Возможно, кто-то, столкнувшийся с такой же проблемой, найдет это полезным (строки с комментариями у меня не сработали, но, возможно, кто-то может настроить их для работы)

 CREATE FUNCTION lang_to_tsconfig(text) RETURNS regconfig
   LANGUAGE sql IMMUTABLE STRICT AS
$$SELECT CASE
WHEN $1 = 'ar' THEN 'arabic'::regconfig
-- WHEN $1 = 'be' THEN 'belarusian'::regconfig
-- WHEN $1 = 'bg' THEN 'bulgarian'::regconfig
-- WHEN $1 = 'bs' THEN 'bosnian'::regconfig
-- WHEN $1 = 'cs' THEN 'czech'::regconfig
WHEN $1 = 'da' THEN 'danish'::regconfig
WHEN $1 = 'de' THEN 'german'::regconfig
--WHEN $1 = 'el' THEN 'greek'::regconfig
WHEN $1 = 'en' THEN 'english'::regconfig
WHEN $1 = 'es' THEN 'spanish'::regconfig
--WHEN $1 = 'et' THEN 'estonian'::regconfig
WHEN $1 = 'fi' THEN 'finnish'::regconfig
WHEN $1 = 'fr' THEN 'french'::regconfig
--WHEN $1 = 'he' THEN 'hebrew'::regconfig
--WHEN $1 = 'hr' THEN 'croatian'::regconfig
WHEN $1 = 'hu' THEN 'hungarian'::regconfig
WHEN $1 = 'id' THEN 'indonesian'::regconfig
--WHEN $1 = 'is' THEN 'icelandic'::regconfig
WHEN $1 = 'it' THEN 'italian'::regconfig
--WHEN $1 = 'ja' THEN 'japanese'::regconfig
--WHEN $1 = 'ko' THEN 'korean'::regconfig
WHEN $1 = 'lt' THEN 'lithuanian'::regconfig
--WHEN $1 = 'lv' THEN 'latvian'::regconfig
WHEN $1 = 'nl' THEN 'dutch'::regconfig
WHEN $1 = 'no' THEN 'norwegian'::regconfig
--WHEN $1 = 'pl' THEN 'polish'::regconfig
WHEN $1 = 'pt' THEN 'portuguese'::regconfig
WHEN $1 = 'ro' THEN 'romanian'::regconfig
WHEN $1 = 'ru' THEN 'russian'::regconfig
--WHEN $1 = 'sk' THEN 'slovak'::regconfig
--WHEN $1 = 'sl' THEN 'slovenian'::regconfig
--WHEN $1 = 'sr' THEN 'serbian'::regconfig
WHEN $1 = 'sv' THEN 'swedish'::regconfig
WHEN $1 = 'tr' THEN 'turkish'::regconfig
--WHEN $1 = 'uk' THEN 'ukrainian'::regconfig
--WHEN $1 = 'vi' THEN 'vietnamese'::regconfig
--WHEN $1 = 'zh' THEN 'chinese'::regconfig
         END$$;