我正在使用Sphinx和Thinking Sphinx插件来搜索我的数据。我正在使用MySQL。

我的数据包含重音字符(“á”,“é”,“ã”),我希望它们等同于它们的非重音字符(“a”,“e”,“搜索和订购时的“例如”。

我使用charset表(pastie.org/204316)进行搜索,并搜索“AGUA”。返回“ÁGUA”,但结果的排序不正常。在搜索“AGUA”时,“ÁGUA”与“AGUA”相同。例如,在“MUITAÁGUA”之后出现,但是我希望它被分类,好像它是用“A”编写的,而不是“Á”。

我能想到的唯一解决方案是索引一个包含非重音字符的新列,并使用REPLACE将其用于分类( http://dev.mysql.com/doc/refman/5.4/en/string-functions.html#function_replace )mysql函数去除重音字符,但是我需要为每个可能的重音字符调用REPLACE(并且有很多),在我看来这是一个不太可行的解决方法。

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

谢谢!

有帮助吗?

解决方案

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所以你可以调用你的替换方法。

使用以下语法在小写版本上构建索引。它是使用 Sphinx 进行不区分大小写搜索的非常简单和优雅的解决方案。

indexes title, as: :title, sortable: :insensitive
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top