質問

SphinxとThinking Sphinxプラグインを使用してデータを検索しています。 MySQLを使用しています。

データにアクセント記号付きの文字("á"、"é"、"ã")が含まれており、アクセント記号のない対応する文字(たとえば、「a」、「e」、「a」など)を検索および順序付けします。

文字セットテーブル(pastie.org/204316)を使用して検索を実行し、「AGUA」を検索しました。 「Á GUA」を返しますが、結果の順序が正しく機能していません。 「AGUA」、「Á GUA」の検索では、たとえば、「MUITAÁ GUA」の後にありますが、「Á」ではなく「A」で書かれているかのようにソートしたかったのです。

私が考えることができる唯一の解決策は、アクセント記号のない文字を含む新しい列にインデックスを付け、REPLACE( http://dev.mysql.com/doc/refman/5.4/en/string-functions.html#function_replace )mysql関数アクセント記号付きの文字を削除するには、可能なアクセント記号付き文字ごとにREPLACEを1回呼び出す必要があり(多くあります)、私にはあまり保守できない回避策のようです。

誰もがこの問題を処理するためのより良い方法を知っていますか?

ありがとう!

役に立ちましたか?

解決

Sphinxは、リストにすべての値を保存し、リストを並べ替えてから各文字列のインデックスをint属性として保存することにより、文字列フィールドの並べ替えを処理します。文書によると、このリストのソートはバイトレベルで行われ、現在は構成できません。

理想的には、エンコーディングとロケールに応じて、文字列を異なる方法でソートする必要があります。たとえば、文字列がKOI8Rエンコーディングのロシア語テキストであることがわかっている場合、バイト0xE0、0xE1、および0xE2を並べ替えると、0xE1、0xE2、および0xE0が生成されます。 0xE1および0xE2。残念ながら、現時点ではSphinxはそれをサポートしておらず、単に文字列をバイト単位でソートします。

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

つまり、Sphinx内でこれを実現する簡単な方法はありません。 REPLACE()ベースのアイデアを変更するには、別の列を作成し、モデル内のコールバックを使用して列を設定します。これにより、おそらく保守しやすいソリューションであるMySQLの代わりにRubyで置換を処理できます。

# 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

他のヒント

また、dbに新しい列を必要としない特別なインデックスを使用することもできます

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

生のSQLなので、replaceメソッドを呼び出すことができます。

次の構文を使用して、小文字バージョンでインデックスを作成するだけです。 Sphinx を使用した case insensitive 検索のための非常にシンプルでエレガントなソリューション。

indexes title, as: :title, sortable: :insensitive
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top