我正在尝试使用Searchkick在Elasticsearch中创建一个单独的渗滤器索引。我希望SavedSearch
能够渗透Product
索引,因此(我认为)需要SavedSearch
和Product
映射要与添加的相同SavedSearch
映射中的percolator属性。
以下解决方案似乎可行,但也显得笨拙。有人对更好的方法有任何建议吗?
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