Ruby on Rails - 搜索具有多个属性的记录

时间:2017-11-19 18:41:16

标签: ruby-on-rails ruby postgresql search

我已经编写了一些代码来搜索所有Recipe条记录中的几个属性。代码有效,但我想要一些输入,如果它没问题,或者如何使它更好/更快。

我有一个包含name:stringingredients:[array of integers](postgres数据库)等各种属性的配方模型。成分是单独模型Ingredient的ID。这是一次学习经历,我不想使用任何宝石。

我的表格 index.html.erb

<%= form_tag recipes_path, :method => 'get' do %>
  <p>
    <%= text_field_tag :search, params[:search] %>
    <%= collection_select( :ingredients, :ingredient_ids, Ingredient.all, :id, :name, {:include_blank => false, include_hidden: false}, { :multiple => true  } ) -%>
   <%= submit_tag "Search" %>
  </p>
<% end %>

recipes_controller.rb

 def index
    @recipes = Recipe.search(params[:search], params[:ingredients])
  end

recipe.rb

  def self.search(search, ids)
    array = []
    if search && !search.empty?
      meals = where('name ILIKE ?', "%#{search}%")
      meals.each do |meal|
        array.push(meal)
      end
      if ids && !ids.empty?
        ingredients(array, ids)
      else
        return array
      end
    elsif ids && !ids.empty?
      ingredients(all, ids)
    else
      all
    end
  end

  def self.ingredients(meals, ids)
    newarray = []
    if ids
      meals.each do |me|
        a = me.ingredients
        b = ids[:ingredient_ids].map(&:to_i)
        if (b - a).empty?
          newarray.push(me)
        end
      end
      return newarray
    else
      return meals
    end
  end

目前此工作正常,因为我没有很多记录,但我不相信如果我有数百或数千条记录,它会非常快。有关改善事物的建议吗?

1 个答案:

答案 0 :(得分:0)

如果您知道要经常搜索一个或多个列,请尝试为这些列添加数据库级索引。没有索引,任何搜索都将是O(n)时间,其中n是记录数。但是,如果使用索引,则搜索将为O(log(n))时间,因为对于搜索列排序的数据,您可以通过它进行二进制搜索。

请查看http://weblog.rubyonrails.org/2011/12/6/what-s-new-in-edge-rails-explain/,了解有关如何检查查询效果是否可以改进的更多信息。

另外两个要考虑性能的事情:

1)对于你的所有情况,你可能会返回比你想要的更多的记录。你可能想考虑使用分页(我知道你没有提到其他宝石,但有一些great gems用于分页。)

2)如果您确实想要一次返回大量记录,请考虑使用ActiveRecord's batching(我通常使用#find_each)以确保您不会立即将所有内容加载到内存中并最终获得OOM- ING。