Question

J'utilise Sphinx avec le plugin Thinking Sphinx pour rechercher mes données. J'utilise MySQL.

Mes données contiennent des caractères accentués ("& # 225;", "" # 233; "", "& # 227;") et je veux qu'ils soient équivalents à leurs équivalents non accentués ( "a", "e", "a", par exemple) lors de la recherche et de la commande.

La recherche a fonctionné à l'aide d'une table de jeux de caractères (pastie.org/204316), ainsi qu'une recherche sur "AGUA". renvoie "& # 193; GUA", mais le classement des résultats ne fonctionne pas correctement. Dans une recherche sur "AGUA", "& # 193; GUA" cames après "MUITA", par exemple, mais je voulais que le tri soit effectué comme si elle était écrite avec un "A", pas un "& # 193".

La seule solution à laquelle je puisse penser est d’indexer une nouvelle colonne contenant les caractères non accentués et de l’utiliser pour le tri en utilisant REPLACE ( http://dev.mysql.com/doc/refman/5.4/fr/string-functions.html#function_replace ) Fonction mysql supprimer les caractères accentués, mais il me faudrait un appel à REMPLACER pour chaque caractère accentué possible (et il y en a beaucoup), et il me semble que cette solution de contournement n'est pas très maintenable.

Quelqu'un connaît-il une meilleure façon de gérer ce problème?

Merci!

Était-ce utile?

La solution

Sphinx gère le tri des champs de chaîne en stockant toutes les valeurs dans une liste, en triant la liste, puis en enregistrant l'index de chaque chaîne sous la forme d'un attribut int. Selon la documentation, le tri de cette liste s'effectue au niveau octet et n’est actuellement pas configurable.

Idéalement, les chaînes doivent être triées différemment, en fonction du codage et des paramètres régionaux. Par exemple, si les chaînes sont connues pour être du texte russe dans l'encodage KOI8R, le tri des octets 0xE0, 0xE1 et 0xE2 devrait produire 0xE1, 0xE2 et 0xE0, car dans KOI8R, la valeur 0xE0 code un caractère qui est (sensiblement) après les caractères codés par 0xE1 et 0xE2. Malheureusement, Sphinx ne le supporte pas pour le moment et va simplement trier les chaînes de caractères par octet.

- from http://www.sphinxsearch.com/docs/current.html

Donc, aucun moyen facile d’atteindre cet objectif dans Sphinx. Une modification de votre idée basée sur REPLACE () consisterait à avoir une colonne distincte et à la remplir à l'aide d'un rappel dans votre modèle. Cela vous permettrait de gérer le remplacement dans Ruby au lieu de MySQL, une solution sans doute plus facile à gérer.

# 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

Autres conseils

vous pouvez également utiliser un index spécial pour que vous n'ayez même pas besoin d'une nouvelle colonne sur votre base de données

indexes "LOWER(title)", :as => :title,  :sortable => true

son sql brut afin que vous puissiez appeler votre méthode de remplacement.

Il suffit de construire un index sur la version minuscule avec la syntaxe suivante. Sa solution très simple et élégante pour la recherche sans distinction de casse avec Sphinx .

indexes title, as: :title, sortable: :insensitive
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top