Нечувствительный к акценту порядок в Sphinx
-
06-07-2019 - |
Вопрос
Я использую Sphinx с плагином Thinking Sphinx для поиска моих данных.Я использую MySQL.
Мои данные содержат символы с ударением ("á", "é", "â"), и я хочу, чтобы они были эквивалентны своим аналогам без акцента (например, "a", "e", "a") при поиске и упорядочении.
Я запустил поиск, используя таблицу кодировок (pastie.org/204316), и поиск по "AGUA" возвращает "ÁGUA", но упорядочение результатов не работает должным образом.Например, при поиске по "AGUA" после "MUITA ÁGUA" появляется "ÁGUA", но я хотел, чтобы оно было отсортировано так, как если бы оно было написано с "A", а не "Á".
Единственное решение, которое я могу придумать, - это проиндексировать новый столбец, содержащий символы без акцента, и использовать его для сортировки, используя REPLACE (http://dev.mysql.com/doc/refman/5.4/en/string-functions.html#function_replace) функция mysql для удаления символов с ударением, но мне понадобился бы один вызов для ЗАМЕНЫ для каждого возможного символа с ударением (а их много), и мне кажется, что это не очень поддерживаемый обходной путь.
Кто-нибудь знает какой-нибудь лучший способ справиться с этой проблемой?
Спасибо!
Решение
Sphinx обрабатывает сортировку по строковым полям, сохраняя все значения в списке, сортируя список и затем сохраняя индекс каждой строки в качестве атрибута int.Согласно документам, сортировка этого списка выполняется на уровне байтов и в настоящее время не настраивается.
В идеале строки должны быть отсортированы по-разному, в зависимости от кодировки и локали.Например, если известно, что строки представляют собой русский текст в кодировке KOI8R, сортировка байтов 0xE0, 0xE1 и 0xE2 должна привести к 0xE1, 0xE2 и 0xE0, потому что в KOI8R значение 0xE0 кодирует символ, который находится (заметно) после символов, закодированных 0xE1 и 0xE2.К сожалению, Sphinx на данный момент не поддерживает это и просто отсортирует строки по порядку.
-- из http://www.sphinxsearch.com/docs/current.html
Таким образом, в Sphinx нет простого способа достичь этого.Модификацией вашей идеи, основанной на REPLACE(), было бы создать отдельный столбец и заполнить его с помощью обратного вызова в вашей модели.Это позволило бы вам обрабатывать замену в Ruby вместо MySQL, что, возможно, является более ремонтопригодным решением.
# save an unaccented copy of your title. Normalise method borrowed from
# http://stackoverflow.com/questions/522715/removing-accents-diacritics-from-string-while-preserving-other-special-chars-tri
class MyModel < ActiveRecord::Base
before_validation :update_sort_col
private
def update_sort_col
sort_col = self.title.to_s.mb_chars.normalize(:kd).gsub(/[^-x00-\x7F]/n, '').to_s
end
end
Другие советы
вы также можете использовать специальный индекс для этого вам даже не нужен новый столбец в вашей базе данных
indexes "LOWER(title)", :as => :title, :sortable => true
это необработанный sql, так что вы можете вызвать свой метод replace .
Просто создайте индекс для версии в нижнем регистре со следующим синтаксисом.Это очень простое и элегантное решение для case insensitive
поиск с помощью Sphinx
.
indexes title, as: :title, sortable: :insensitive