Вопрос

Я использую 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top