Я пытаюсь создать отдельный индекс перколятора в 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