4

我正在使用 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,在我看来,这似乎不是一个非常可维护的解决方法。

有人知道一些更好的方法来处理这个问题吗?

谢谢!

4

3 回答 3

3

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
于 2009-06-22T23:49:44.760 回答
1

你也可以使用一个特殊的索引,你甚至不需要你的数据库上的一个新列

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

它的原始 sql 所以你可以调用你的替换方法。

于 2011-01-19T22:29:55.000 回答
0

只需使用以下语法在小写版本上构建索引。它非常简单而优雅的case insensitive搜索解决方案Sphinx

indexes title, as: :title, sortable: :insensitive
于 2016-08-04T06:31:22.300 回答