Схожесть строк utf-8 в postgresql 10.1 - PullRequest
0 голосов
/ 27 ноября 2018

:) Я пытаюсь найти сходство строк в PostgreSQL 10.1.

Я использую расширения unaccent и pg_trgm и включаю их с помощью:

create extension unaccent;
create extension pg_trgm;

Проблемав том, что pg_trgm не обеспечивает поддержку utf8.Поэтому, если я выполню:

select similarity('כפיר','כפיר');

, он возвращает сходство, равное нулю.

Я решил преобразовать эту строку в кодировку iso-8859-8, которая поддерживает иврит и английский, языки, которые я использую вв этом случае.

Но сначала я хочу unaccent строку, поэтому, если у меня есть כפיר - ƒ, она сначала будет преобразована в כפיר - f, поэтому она будет должным образом преобразована в требуемую кодировку символов.

Итак, select unaccent('כפיר - ƒ'); возвращает правильные результаты.

Так что, к сожалению, выполнение:

select convert(unaccent('כפיר - ƒ'),'UTF8','ISO_8859_8');

возвращает

[42883] ОШИБКА: преобразование функции(текст, неизвестно, неизвестно) не существует Подсказка: ни одна функция не соответствует заданному имени и типу аргумента.Возможно, вам придется добавить явные приведения типов.Положение: 8

Когда я проверяю документацию по https://www.postgresql.org/docs/9.1/functions-string.html относительно функции convert(), для нее требуется строка.

Если я пытаюсь что-то преобразовать в строку, яполучить это type "string" does not exist

ОК.Поэтому работа с unaccent - это первая проблема, которую мне нужно решить (и, возможно, единственная проблема).То, что я сделал дальше, дало правильные результаты, и я не увидел правильную строку на иврите.

Я имею в виду следующее:

Выполнение select convert('כפיר','UTF-8','ISO_8859_8'); возвращает

4 B 00000000  EB F4 E9 F8                                        ëôéø

иприведение к тексту с помощью select convert('כפיר','UTF8','ISO_8859_8')::text; возвращает \xebf4e9f8

Я предполагаю, что это символы записи, и из-за изменения кодировки я не вижу настоящие ивритские символы.я ошибаюсь, чтобы предположить это?это вторая проблема.

Так что, если я не использую ударение и выполняю:

select similarity(convert('כפייר עזר','UTF8','ISO_8859_8')::text, convert('כפיר','UTF8','ISO_8859_8')::text);

, возвращается значение 0,5, что нормально.

Подводя итогмои вопросы:

  1. Как правильно разыграть unaccent, чтобы можно было использовать его в convert
  2. Правильно ли я приводил свою строку иврита utf-8 в ASCII?
  3. Я пытаюсь решить проблему правильным способом - есть ли другое расширение для функции подобия, которая поддерживает utf-8?
  4. Я также хочу удалить любой символ, который не является буквенно-цифровым, из строки, прежде чем я выполню функцию подобия, чтобы получить лучшие результаты сходства, основанные на моих потребностях.Я думаю об использовании регулярных выражений о преобразовании строки в ASCII.что-то вроде: regexp_replace('string', '\W+', '', 'g').Это путь?Есть ли regexp_replace, которое поддерживает utf8?

Спасибо!

1 Ответ

0 голосов
/ 27 ноября 2018

хорошо, так что решение было простым.

необходимо преобразовать в байтовый массив (bytea) и затем обратно в текст.и что касается замены регулярного выражения, я должен был использовать определенные символы, которые я хотел удалить, вместо использования \W+.

, поэтому решение для моего случая:

   select
  similarity(convert(unaccent(regexp_replace(lower('string'), '[.,''׳`"-]', '', 'g'))::bytea,'UTF8','ISO_8859_8')::text,
             convert(unaccent(regexp_replace(lower('string'), '[.,''׳`"-]', '', 'g'))::bytea,'UTF8','ISO_8859_8')::text)
...