Создание отдельного индекса перколятора для Elasticsearch с использованием Searchkick (Rails) - PullRequest
0 голосов
/ 03 июля 2019

Я пытаюсь создать отдельный индекс перколятора в Elasticsearch, используя Searchkick .Я бы хотел, чтобы SavedSearch мог фильтровать индекс Product, и поэтому (я полагаю) необходимо, чтобы сопоставления SavedSearch и Product были одинаковыми с добавлением свойства percolator в сопоставлении SavedSearch.

Решение, представленное ниже, похоже, работает, но также кажется неуклюжим.Кто-нибудь есть какие-либо предложения для лучшего способа сделать это?

class Product < ApplicationRecord
  searchkick callbacks: false, batch_size: 200

  def self.mappings_for_percolator
    _mapping_name, full_mapping = Product.search_index.mapping.max_by { |k, _v|
      Time.parse(k[/\d+/])
    }

    mapping = full_mapping["mappings"]["product"]
    mapping["properties"]["query"] = { "type" => "percolator" }
    mapping
  end
end

class SavedSearch < ApplicationRecord
  searchkick merge_mappings: true, mappings: {
    saved_search: Product.mappings_for_percolator
  }

  validates :query, presence: true
  validate :query_is_valid

  def self.percolate_product(id)
    q = {
      query: {
        constant_score: {
          filter: {
            percolate: {
              field: "query",
              index: Product.search_index.name,
              type: "product",
              id: id
            }
          }
        }
      }
    }

    search(body: q.to_json)
  end

  def query_is_valid
    result = Searchkick.client.perform_request(
      "GET",
      "#{Product.search_index.name}/_validate/query",
      {},
      { query: query }.to_json
    ).body

    return if result["valid"]

    errors.add(:query, "is invalid")
  end
end
...