Дано: PostgreSQL 8.3.1.
Задача: реализовать поиск по тексту независимым от латышских диакритических символов. Т.е. по запросу «ē», должны быть найдены и «e», и «ē» и наоборот.
Латышский язык содержит следующие диакритические знаки (wikipedia):
- гарумзиме: ā ē ī ū,
- гачек: č š ž,
- седиль: ģ ķ ļ,
и всем этим буквам соотвествуют обычные латинские, без дополнений.
Сначала, для тех кто ищет просто решение - функция, которая заменяет буквы с диакритическими знаками на обычные:
CREATE OR REPLACE FUNCTION unaccent_string(text) RETURNS text LANGUAGE SQL IMMUTABLE STRICT AS $$ SELECT replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( ( SELECT replace( replace( replace( replace( replace( replace( replace( replace( replace( replace( replace($1, \'ā\', \'a\'), \'ž\', \'z\'), \'ū\', \'u\'), \'š\', \'s\'), \'ņ\', \'n\'), \'ļ\', \'l\'), \'ķ\', \'k\'), \'ī\', \'i\'), \'ģ\', \'g\'), \'ē\', \'e\'), \'č\', \'c\') AS "text") , \'Ā\', \'A\'), \'Ž\', \'Z\'), \'Ū\', \'U\'), \'Š\', \'S\'), \'Ņ\', \'N\'), \'Ļ\', \'L\'), \'Ķ\', \'K\'), \'Ī\', \'I\'), \'Ģ\', \'G\'), \'Ē\', \'E\'), \'Č\', \'C\') AS "text"; $$;
Не имея понятия с чего начать, я попытался найти какое-то готовое решение. Мне попалась идея замены букв на обычные с помощью функции translate(). Отсюда и начал:
~~
SELECT translate('Cātozzo', 't', 'a2') AS "res"
res: Cāaozzo
~~
простой символ заменяется как и ожидалось, но:
~~
SELECT translate('Cātozzo', 'ā', 'a2') AS "res"
res: Ca2tozzo
~~
utf-символ воспринимается функцией translate как два, и каждая половинка заменяется отдельно (таков принцип работы функции). Первая часть utf-символа повторяется у разных букв, поэтому вариант с translate() не работает или сильно усложняется.
Тогда я решил попробовать replace, что и дало мне функцию указанную вначале статьи. Тест:
~~
SELECT unaccent_string(\'glāžšķūņu rūķīši\') AS "res"
res: glazskunu rukisi
SELECT unaccent_string(\'GLĀŽŠĶŪŅU RŪĶĪŠI\') AS "res"
res: GLAZSKUNU RUKISI
~~
Комментариев нет:
Отправить комментарий