【问题标题】:Ignore uppercase, downcase and accent in search在搜索中忽略大写、小写和重音
【发布时间】:2017-02-25 10:11:31
【问题描述】:

我有一个带有过滤器here 的搜索系统。这个系统就像一个魅力,但我在小写/大写和重音方面遇到了一些问题。

例如,如果我搜索“marée”,我会得到结果,但如果我搜索“MAREE”或“Marée”或“maree”。我没有结果。

我想解决这个问题。我该如何解决这个问题?谢谢。

我的控制器

    def resultnohome
          if params[:query].blank?
            redirect_to action: :index and return
          else
          @campings = Camping.searchi(params[:query], params[:handicap], params[:animaux], params[:television], params[:plage], params[:etang], params[:lac])
            if params[:query] == "aube"
              @pub = Camping.find_by_id(1)
            else
            end
        end
end

我的模型

 def self.searchi(query, handicap, animaux, television, plage, etang, lac)
    return scoped unless query.present?
         result = left_outer_joins(:caracteristiquetests, :situations).where('nomdep LIKE ? OR name LIKE ? OR nomregion LIKE ? OR commune LIKE?', "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%")
         result = result.where('handicap LIKE ?', "%#{handicap}%") if handicap
         result = result.where('animaux LIKE ?', "%#{animaux}%") if animaux
         result = result.where('television LIKE ?', "%#{television}%") if television
         result = result.where('plage LIKE ?', "%#{plage}%") if plage
         result = result.where('etang LIKE ?', "%#{etang}%") if etang
         result = result.where('lac LIKE ?', "%#{lac}%") if lac
      return result
  end

【问题讨论】:

  • 完全取决于您使用的数据库。 Postgres 有一个ILIKE 关键字,它将执行不区分大小写的搜索。在 MYSQL 中,您使用较低的函数WHERE "foo" LIKE %LOWER("Bar")%
  • @max 我目前使用 SQLite。你有什么想法吗?
  • 不要使用 SQLite,它是一个玩具数据库。专注于您稍后将在生产中使用的数据库。我会选择 Postgres
  • 我想我会选择 Mysql。但是目前在生产中你对我的问题有什么想法吗?

标签: ruby-on-rails search params


【解决方案1】:

如果你坚持使用 SQLite,那么你没有很多好的选择。最常见的建议是在您的数据库中添加额外的列,这些列是标准化值,因此如果您的 plage 列包含“Marée”,那么您还有一个包含“maree”的列 plage_ascii

您需要创建带有迁移的附加列,然后您的模型中将有一个 before_save 操作...

before_save :create_normalized_strings

def create_normalized_strings
  self.handicap_ascii = handicap.downcase.mb_chars.normalize(:kd).gsub(/[^x00-\x7F]/n, '').to_s
  self.animaux_ascii = animaux.downcase.mb_chars.normalize(:kd).gsub(/[^x00-\x7F]/n, '').to_s
  # etc etc
end

然后在您的搜索中...

if handicap
  test_handicap = handicap.downcase.mb_chars.normalize(:kd).gsub(/[^x00-\x7F]/n, '').to_s
  result = result.where('handicap_ascii LIKE ?', "%#{handicap}%")
end

这不是很好,因为它基本上会迫使您将数据库中的数据复制到额外的列中。如果您可以考虑 SQLite 以外的更复杂的数据库,那么您会更好……我个人不会在生产环境中使用 SQLite。

【讨论】:

  • 感谢您的回复 :) 肯定另一栏不太好 :S 对您来说最好的方法是什么? MySQL ?后格雷斯?如果我改变了,用另一个数据库解决我的问题的方法是什么?
  • 我真的很喜欢 PostgreSQL。它具有配置“unaccent”方法的功能,因此您可以...
  • 太棒了!这正是我需要的。我会要求 Google 在 Rails 中为 PostgreSQL 更改我的 sqlite ;)
猜你喜欢
  • 2011-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-11
  • 2015-01-15
  • 1970-01-01
  • 1970-01-01
  • 2020-05-28
相关资源
最近更新 更多