Поддерживает ли PostgreSQL параметры сортировки, нечувствительные к акценту?



В Microsoft SQL Server можно указать параметры сортировки" без акцента " (для базы данных, таблицы или столбца), что означает, что это возможно для запроса типа



SELECT * FROM users WHERE name LIKE 'João'


чтобы найти строку с Joao имя.



Я знаю, что можно удалить акценты из строк в PostgreSQL с помощью unaccent_string функция contrib, но мне интересно, поддерживает ли PostgreSQL эти" нечувствительные к акценту " параметры сортировки, поэтому SELECT выше работа.

627   3  

3 ответов:

используйте модуль unaccent для этого - что совершенно отличается от того, что вы связываете.

unaccent является поиск текста словаря, который удаляет акценты (диакритические знаки) от лексем.

установить один раз на базу данных с:

CREATE EXTENSION unaccent;

если вы получаете сообщение об ошибке, как:

ошибка: не удалось открыть файл управления расширением "/usr / share/postgresql / 9.x / extension / unaccent.контроль": Нет такого файла или каталог

установите пакет contrib на сервер базы данных, как указано в этом соответствующем ответе:

среди прочего, он обеспечивает функцию unaccent() вы можете использовать с вашим примером (где LIKE кажется, не необходимый.)

SELECT *
FROM   users
WHERE  unaccent(name) = unaccent('João');

индекс

использовать индекс для такого рода запросов, создать индекс по выражению. , и Postgres принимает только IMMUTABLE функции для индексов. Если функция может возвращать другой результат для одного и того же ввода, индекс может молча прерваться.

unaccent() только STABLE не IMMUTABLE

к сожалению, unaccent() только STABLE, а не IMMUTABLE. Согласно этот нить на pgsql-баги, это из-за три причины:

  1. это зависит от поведения словарь.
  2. нет жесткого подключения к этому словарю.
  3. поэтому он также зависит от текущего search_path, который может легко измениться.

обучение в интернете поручите просто изменить волатильность функции на IMMUTABLE. Этот метод грубой силы может сломать под ряд условий.

другие предлагаю простой IMMUTABLE функции-оболочки (как и я сам в прошлом).

идет постоянная дискуссия, стоит ли делать вариант с двумя параметрамиIMMUTABLE, который прямо заявляет, использовать словарь. Читайте здесь или здесь.

Другой альтернативой был бы этот модуль с неизменный unaccent() функция Musicbrainz, предоставлено на Github. Не проверял это сам. Я думаю, что я придумал лучшая идея:

лучше на данный момент

я предлагаю подход, который по крайней мере так же эффективно, как и другие решения, плавающие вокруг, но безопаснее: Создайте функцию-оболочку с двухпараметрической формой и" жесткой " схемой для функции и словаря:

CREATE OR REPLACE FUNCTION public.f_unaccent(text)
  RETURNS text AS
$func$
SELECT public.unaccent('public.unaccent', )  -- schema-qualify function and dictionary
$func$  LANGUAGE sql IMMUTABLE;

public будучи схемой, где вы установили расширение (public по умолчанию).

ранее, я добавил SET search_path = public, pg_temp к функции-пока я не обнаружил, что словарь также может быть квалифицирован схемой,который в настоящее время (стр. 10) не документирован. Эта версия немного короче и примерно в два раза быстрее в моих тестах на pg 9.5 и pg 10.

обновленная версия по-прежнему не позволяет функция inlining потому что функции, объявленные IMMUTABLE не может называть не неизменяемым функции в теле, чтобы позволить это. Вряд ли имеет значение для производительности при использовании индекс выражение на :

CREATE INDEX users_unaccent_name_idx ON users(public.f_unaccent(name));

безопасность клиентских программ была усилена с помощью Postgres 10.3 / 9.6.8 и т. д. Ты нужно для определения схемы функции и словаря, как показано при использовании в любых индексах. Смотрите:

  • 'словарь "unaccent" не существует записи в журнал postgres, предположительно во время автоматического анализа

адаптировать запросы в соответствии с индексом (так что планировщик запросов может использовать его):

SELECT * FROM users
WHERE  f_unaccent(name) = f_unaccent('João');

вам не нужна функция в правильном выражении. Вы можете поставить безымянные строки, такие как 'Joao' напрямую.

лигатур

В Postgres 9.5 и старше лигатуры, такие как' Œ 'или' β', должны быть расширены вручную (Если вам это нужно), так как unaccent() всегда заменяет один письмо:

SELECT unaccent('Œ Æ œ æ ß');

unaccent
----------
E A e a S

вы будете любить это обновление, чтобы unaccent в Postgres 9.6:

расширения contrib/unaccent'стандарт s unaccent.rules файл для обработки всех диакритические знаки, известные в Юникоде, и правильно развернуть лигатуры (Томас Мунро, Леонард Бенедетти)

жирным выделено мной. Теперь мы получаем:

SELECT unaccent('Œ Æ œ æ ß');

unaccent
----------
OE AE oe ae ss

шаблон соответствие

на LIKE или ILIKE с произвольными шаблонами, объедините это с модулем pg_trgm в PostgreSQL 9.1 или более поздней версии. Создайте триграмму Gin (обычно предпочтительно) или индекс выражения GIST. Пример для Джина:

CREATE INDEX users_unaccent_name_trgm_idx ON users
USING gin (f_unaccent(name) gin_trgm_ops);

может использоваться для таких запросов, как:

SELECT * FROM users
WHERE  f_unaccent(name) LIKE ('%' || f_unaccent('João') || '%');

индексы GIN и GIST дороже в обслуживании, чем простые дерево:

есть более простые решения для только левых якорных шаблонов. Подробнее о сопоставлении шаблонов и производительности:

pg_trgm также предоставляет полезную операторы для "подобия" (%) и "расстояние" (<->).

индексы триграмм также поддерживают простые регулярные выражения с ~ и соавт. и регистр сопоставление сILIKE:

Я уверен, что PostgreSQL полагается на базовую операционную систему для сортировки. Это тут поддержка создание новых параметров сортировки и настройка параметров сортировки. Хотя я не уверен, сколько работы это может быть для вас. (Может быть довольно много.)

нет, PostgreSQL не поддерживает параметры сортировки в этом смысле

PostgreSQL не поддерживает такие параметры сортировки (нечувствительные к акценту или нет), потому что никакое сравнение не может вернуть равенство, если только вещи не являются двоичными. Это связано с тем, что внутри он будет вводить много сложностей для таких вещей, как хэш-индекс. По этой причине сопоставления в их самом строгом смысле влияет только на заказ и не равенство.

решения

словарь полнотекстового поиска, который не содержит лексем.

для FTS вы можете определить свой собственный словарь с помощью unaccent,

CREATE EXTENSION unaccent;

CREATE TEXT SEARCH CONFIGURATION mydict ( COPY = simple );
ALTER TEXT SEARCH CONFIGURATION mydict
  ALTER MAPPING FOR hword, hword_part, word
  WITH unaccent, simple;

который вы можете затем индексировать с функциональным индексом,

-- Just some sample data...
CREATE TABLE myTable ( myCol )
  AS VALUES ('fóó bar baz'),('qux quz');

-- No index required, but feel free to create one
CREATE INDEX ON myTable
  USING GIST (to_tsvector('mydict', myCol));

теперь вы можете запросить его очень просто

SELECT *
FROM myTable
WHERE to_tsvector('mydict', myCol) @@ 'foo & bar'

    mycol    
-------------
 fóó bar baz
(1 row)

см. также

Unaccent сам по себе.

The unaccent модуль может также использоваться сам по себе без FTS-интеграции, для этого проверьте ответ Эрвина

Comments

    Ничего не найдено.