【问题标题】:Multiple word searching with Ruby, and MySQL使用 Ruby 和 MySQL 进行多词搜索
【发布时间】:2011-03-11 16:56:42
【问题描述】:

我正在尝试使用 Ruby、ActiveRecord 和 MySQL 在报价数据库中完成多字搜索。我的方法如下所示,并且可以正常工作,但是我想知道是否有更好的方法。

# receives a string, splits it in a array of words, create the 'conditions'
# query, and send it to ActiveRecord
def search
    query = params[:query].strip.split if params[:query]
    like = "quote LIKE "
    conditions = ""
    query.each do |word|
        conditions += (like + "'%#{word}%'")
        conditions += " AND " unless query.last == word
    end
    @quotes = Quote.all(:conditions => conditions)
end

我想知道是否有更好的方法来组成这个“条件”字符串。我还尝试使用字符串插值,例如使用 * 运算符,但最终需要更多的字符串处理。提前致谢

【问题讨论】:

    标签: mysql ruby search activerecord


    【解决方案1】:

    首先,我强烈建议您将模型的逻辑转移到模型中。不要在 Controller 中创建搜索逻辑,而是在 Quote 模式中创建 #search 方法。

    class Quote
      def self.search(query)
        ...
      end
    end
    

    你的控制器变成了

    # receives a string, splits it in a array of words, create the 'conditions'
    # query, and send it to ActiveRecord
    def search
      @quotes = Quote.search(params[:query])
    end
    

    现在,回到最初的问题。您现有的搜索逻辑犯了一个非常严重的错误:它直接插入值打开您的代码以进行 SQL 注入。假设您使用 Rails 3,您可以利用新的 #where 语法。

    class Quote
      def self.search(query)
        words = query.to_s.strip.split
        words.inject(scoped) do |combined_scope, word|
          combined_scope.where("quote LIKE ?", "%#{word}%")
        end
      end
    end
    

    这是一个有点高级的话题。我想了解combined_scope + inject 的作用,我建议你阅读文章The Skinny on Scopes

    【讨论】:

    • 如果你在例子中演示了mysql的全文搜索会很好
    • 我建议 to_s.downcase.strip.split.uniq 折叠成小写并删除重复的单词。
    • 我使用的是 Rails 2.3.5,但无论如何,答案帮助很大。谢谢。
    • Rails 5 更改:将 'scoped' 替换为 'all'。多年来一直在使用这个有用的答案。
    【解决方案2】:

    MySQL 全文搜索不起作用,所以最好的方法是:

    class Quote
      def self.search_by_quote(query)
        words = query.to_s.strip.split
        words.map! { |word| "quote LIKE '%#{word}%'" }
        sql = words.join(" AND ")
        self.where(sql)
      end
    end
    

    【讨论】:

      【解决方案3】:

      更好的方法是实现全文搜索。您可以在MySQL 中执行此操作,但我强烈推荐Solr。有很多资源 online 用于在 Rails 中实现 Solr,但我建议将 Sunspot 作为入口点。

      【讨论】:

      • Solr 确实是一个不错的选择,但是是一个相当复杂的库。在某些情况下,您实际上不需要添加 Solr 依赖项,尝试针对 MySQL 进行此类查询是非常好的。我相信在这种情况下,用户无需尝试 Solr 就可以从重构代码中受益匪浅。
      【解决方案4】:

      在 MySQL 中创建 FULLTEXT 索引。这样,您就可以将字符串处理留给 MySQL。

      例如:http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

      【讨论】:

        猜你喜欢
        • 2017-07-10
        • 1970-01-01
        • 1970-01-01
        • 2019-07-24
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        • 2014-11-18
        相关资源
        最近更新 更多