Использование 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