Использование unaccent в триггере tsvector

Я хотел бы использовать пакет unaccent contrib в моей колонке tsvector. Я успешно установил пакет, используя unaccent create extension, и проверил, работает ли он. Я установил триггер для автоматического обновления столбца tsvector,

CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
ON artists FOR EACH ROW EXECUTE PROCEDURE
tsvector_update_trigger(tsv_name, 'pg_catalog.simple', name);

а затем установите столбец tsv_name во всех существующих строках, используя следующую

UPDATE artists SET tsv_name = (to_tsvector('simple', coalesce(name, '')));

Я думал, что смогу включить unaccent package, просто заменив name на unaccent (name) в приведенном выше коде, но это вызывает синтаксическую ошибку в коде триггера create. Как это исправить, чтобы в столбце tsvector использовались символы без акцента?

0 ответов

Я знаю, что это действительно старый билет, но вместе с невероятным ответом @ErwinBrandstetter ( /questions/7056365/podderzhivaet-li-postgresql-sortirovku-bez-ucheta-aktsenta/7056382#7056382) и чтением некоторых документов PostgreSQL ( https://www.postgresql.org/docs/9.3/functions-textsearch.html), я наконец понял это.

Вот как выглядит моя миграция (с использованием Rails 5.2):


    # Erwin's wrapper code
    connection.execute(<<-EOSQL)
      CREATE OR REPLACE FUNCTION public.immutable_unaccent(regdictionary, text)
        RETURNS text LANGUAGE c IMMUTABLE STRICT AS
        '$libdir/unaccent', 'unaccent_dict';
    EOSQL

    connection.execute(<<-EOSQL)
      CREATE OR REPLACE FUNCTION public.f_unaccent(text)
        RETURNS text LANGUAGE sql IMMUTABLE STRICT AS
      $func$
      SELECT public.immutable_unaccent(regdictionary 'unaccent', $1)
      $func$;
    EOSQL

    # new trigger using f_unaccent
    connection.execute(<<-EOSQL)
      CREATE TRIGGER artists_name_tsvector_update BEFORE INSERT OR UPDATE
      OF name ON artists FOR EACH ROW EXECUTE PROCEDURE
      tsvector_update_trigger(
        tsv_name, 'public.f_unaccent(name)', name
      );

      UPDATE artists SET tsv_name = (to_tsvector('public.f_unaccent(name)', name));
    EOSQL

Это обновление позволяет пользователям выполнять поиск со специальными символами или не давать одинаковые результаты (например, поисковые запросы "Ønders" и "Onders" возвращают правильного исполнителя).

Примечание: я также использую I18n.transliterate для локализации параметра входящего запроса.

Обновлено - при запуске тестов я обнаружил, что мой код ОБНОВЛЕНИЯ был неправильным, поэтому мне пришлось изменить свой код, чтобы он заработал. Я сохраню это на случай, если это кому-то поможет

Обновленная миграция с использованием ответа @EvanCarroll /questions/7056365/podderzhivaet-li-postgresql-sortirovku-bez-ucheta-aktsenta/7056388#7056388 - Я не мог понять, как заставить триггер обновления перестать жаловаться с помощью кода Эрвина.:/

# create extension unaccent
    connection.execute(<<-EOSQL)
      CREATE TEXT SEARCH CONFIGURATION f_unaccent ( COPY = simple );
      ALTER TEXT SEARCH CONFIGURATION f_unaccent
        ALTER MAPPING FOR hword, hword_part, word
        WITH unaccent, simple;
    EOSQL

    # create updated trigger using unaccent for tsv_name
    # update existing tsv_names
    connection.execute(<<-EOSQL)
      CREATE TRIGGER artists_name_tsvector_update BEFORE INSERT OR UPDATE
      OF name ON artists FOR EACH ROW EXECUTE PROCEDURE
      tsvector_update_trigger(
        tsv_name, 'public.f_unaccent', name
      );

      UPDATE artists SET tsv_name = (to_tsvector('public.f_unaccent', name));
    EOSQL
Другие вопросы по тегам