0

2 つの異なるテーブルから 3 つの異なる列をクエリする 1 つの検索フィールドがあります。位置テーブルの「会社」と「産業」、および教育テーブルの「学校」です。(select_tag を使用して) 検索フィールドに入力されたすべてのフィールドを満たすすべてのユーザーを正常に返しています。これは私の見解です:

  <%= form_tag(search_path, :method => :get, :id => "people_search") do %>
    <div class="row-fluid">  
      <div class="span4">
        <table>
          <tr>
            <td>
              <div class="search-table" style="padding-left:55px">
                <%= select_tag "all", options_for_select((@visible_companies + @visible_industries + @visible_schools).uniq, params[:all]), { :placeholder => "Search by companies, industries and schools...", :multiple => true, :js => "if (evt.keyCode == 13) {form.submit();}" } %>
              </div>
            </td>
            <td>
              <%= submit_tag "Add", id: "send-button", style:"width:175px;" %>
            </td>
          </tr>
        </table>
      </div>
    <% end %>
  </div>

およびコントローラー:

    @visible_positions = Position.where{ is_visible.eq('true') }
    @visible_educations = Education.where{ is_visible.eq('true') }

    @visible_companies = @visible_positions.order("LOWER(company)").map(&:company).uniq
    @visible_industries = @visible_positions.order("LOWER(industry)").map(&:industry).uniq
    @visible_schools = @visible_educations.order("LOWER(school)").map(&:school).uniq

    @c = @visible_positions.where{company.in(my{params[:all]})}.map(&:user_id)
    @i = @visible_positions.where{industry.in(my{params[:all]})}.map(&:user_id)
    @s = @visible_educations.where{school.in(my{params[:all]})}.map(&:user_id)

    @C = @visible_positions.where{company.in(my{params[:all]})}.map(&:company)
    @I = @visible_positions.where{industry.in(my{params[:all]})}.map(&:industry)
    @S = @visible_educations.where{school.in(my{params[:all]})}.map(&:school)

    @blacklist = []    
    @cis = @c + @i + @s
    @experiences = ([@C,@I,@S].reject(&:empty?).reduce(:&))

    @cis.uniq.each do |user_id|

      unless @C.empty?
        @C.uniq.each do |company|
          unless Position.find_all_by_company(company).map(&:user_id).include?(user_id) || Position.find_all_by_industry(company).map(&:user_id).include?(user_id) || Education.find_all_by_school(company).map(&:user_id).include?(user_id)
            @blacklist << user_id
          end
        end
      end
      unless @I.empty?
        @I.uniq.each do |industry|
          unless Position.find_all_by_industry(industry).map(&:user_id).include?(user_id) || Position.find_all_by_company(industry).map(&:user_id).include?(user_id) || Education.find_all_by_school(industry).map(&:user_id).include?(user_id)
            @blacklist << user_id
          end
        end
      end
      unless @S.empty?
        @S.each do |school|
          unless Education.find_all_by_school(school).map(&:user_id).include?(user_id) || Position.find_all_by_company(school).map(&:user_id).include?(user_id) || Position.find_all_by_industry(school).map(&:user_id).include?(user_id)
            @blacklist << user_id
          end
        end
      end

    end

    unless @c.empty? && @i.empty? && @s.empty?
      @users = User.find(@cis - @blacklist)
    end

検索は次のようになります (単一のフィールドに注目してください)。サンプル クエリが含まれています (AND フィルターに注目してください...データベース内で、すべての検索語に適合するユーザーは私だけです [学校の場合は「ダートマス大学」、「世界の健康」)会社の場合は「組織」、産業の場合は「インターネット」]):

ここに画像の説明を入力

これは効率的なクエリではないことを認識しており、高速化する方法を考えていますが、この時点でいくつかのアイデアを使用できます。

幸せな七面鳥の日:)

4

1 に答える 1

1

あなたのコードを理解するのではなく、あなたの説明に基づいて、私はこのようなものを見つけました

User.joins(:positions, :educations).where("lower(positions.company) like lower(?) and lower(positions.industry) like lower(?) and lower(educations.school) like lower(?) and positions.is_visible and educations.is_visible", "%#{company}%", "%#{industry}%", "%#{school}%")

または、列に会社または業界が 1 つしかない場合

User.joins(:positions, :educations).where("(lower(positions.company) = lower(?) or lower(positions.industry) = lower(?)) and lower(educations.school) = lower(?) and positions.is_visible and educations.is_visible", company,industry, school)

しかし、多くの業界、企業、学校をパラメーターとして配置すると、より複雑になり、インデックスが作成されます。

create index positions_lower_company on positions (lower(company));
create index positions_lower_industry on positions (lower(industry));
create index educations_lower_school on educations (lower(school));

それが何らかの形で役立つことを願っています。

于 2012-11-22T21:37:34.900 に答える