ruby-on-rails - Sphinx 中的重音不敏感排序

标签 ruby-on-rails search sphinx thinking-sphinx diacritics

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

我的数据包含重音字符(“á”、“é”、“ã”),我希望它们在搜索和订购。

我使用字符集表 (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 调用一次重音字符(有很多),在我看来,这是一个不太容易维护的解决方法。

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

谢谢!

最佳答案

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

关于ruby-on-rails - Sphinx 中的重音不敏感排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1029204/

相关文章:

ruby-on-rails - 使用 ActiveRecord 3/Arel 查找单个记录的最佳方法?

java - 在 HashSet 中搜索

mysql - 关于 sphinx 段规则

lucene - Lucene和Sphinx支持前缀匹配吗?

ruby-on-rails - 尝试安装 rubber gem,Nokogiri 把它搞砸了?

ruby-on-rails - 在 Controller 中访问 helper setter

ruby-on-rails - Rails 功能测试 : sending URL query parameters in POST request

Java二分查找有多个结果吗?

javascript - 如何在没有后端的 Bootstrap (Metronic)上构建的模板中实现搜索功能?

php - Sphinx/MySQL UTF8 &™ 符号