Создание правильного поискового запроса с помощью gem Tire и ElasticSearch

Я пытаюсь реализовать простой поисковый запрос для моего Цветочного магазина, но, поскольку я новичок в Tire и ElasticSearch, я не могу понять, как это сделать.

У меня есть модель Product с возможностью поиска и модели habtm Category, Colour, Flower. Я хочу установить флажки для каждой ассоциации, создав запрос, похожий на этот:

http://example.com/search?q=some%20query&category_names[]=bouquet&category_names[]=marriage&colour_names[]=red&colour_names[]=yellow&colour_names[]=white&flower_names[]=rose&flower_names[]=tulip&price_min=100&price_max=1000

Но мне нужно показать только те товары, которые:

a) prestent in any of the requested categories (OR);
b) have all of the requested colours (AND);
c) have all of the requested flowers (AND);
d) enter the price range between price_min and price_max.

Параметр q предназначен для поиска любого текста, введенного в текстовое поле, в именах ассоциаций (скажем, red roses bouquet), и показывать его тоже с верхними критериями.

Пока у меня есть только

class Product
  include Mongoid::Document

  include Tire::Model::Search
  include Tire::Model::Callbacks

  has_and_belongs_to_many :categories
  has_and_belongs_to_many :colours
  has_and_belongs_to_many :flowers

  def self.search(params)
    tire.search(load: true, page: params[:page], per_page: 8) do |search|
      search.query  { string params[:query] } if params[:query].present?
    end
  end

  def to_indexed_json
    self.to_json(methods: [:category_names, :colour_names])
  end

  def category_names
    self.categories.collect { |c| c.name }
  end

  def colour_names
    self.colours.collect { |c| c.name }
  end
end

и не знаю как настроить. Я читал про filters и facets, но так как английский мне не родной я не могу понять что к чему и как ими пользоваться.


person Yuri Sidorov    schedule 25.10.2012    source источник


Ответы (1)


Я сделал это так:

def self.search(params)
  tire.search(load: true, page: params[:page], per_page: 8) do
    query do
      boolean do
        must { string params[:query], default_operator: "AND" } if params[:query].present?
        must { string params[:category_names] } if params[:category_names].present?
        must { string params[:colour_names], default_operator: "AND" } if params[:colour_names].present?
        must { range :price, { gte: params[:price_min], lte: params[:price_max] } } if params[:price_min].present? && params[:price_max].present?
      end
    end

    # raise to_curl
  end
end
person Yuri Sidorov    schedule 29.10.2012