考虑以下模型
class MyModel # `Employee` used in concrete examples
field :field1 # company_name used in concrete examples
field :field2 # job_name used in concrete examples
scope: filter1 # non_retired
scope: filter2
end
我把所有这些放在一起有问题。从Rails elasticsearch - named scope search开始,我了解到我需要将ID直接提供给Elasticsearch。
def search_by_id(query, type, ids, options = {})
self.weighted_search(query, options.deep_merge({
query: {
multi_match: {
filter: {
ids: {
values: ids
}.tap do |filter|
filter[:type] = type if type
end
}
}
}
}))
end
def weighted_search(query, options = {})
self.__elasticsearch__.search(
{
query: {
multi_match: {
query: query,
fields: [
"company_name^3",
"job_name^2",
],
# strategy: 'leap_frog_filter_first'
# PROBLEM :cannot use this strategy on multi_match ?
}
}
}.deep_merge(options)
)
end
这会产生BadRequest错误,并带有以下说明
[400] {“error”:{“root_cause”:[{“type”:“query_parsing_exception”,“reason”:“[match] query不支持[$ oid]
我不明白这个错误......我无法按ID过滤?
然后,假设我有这个工作,如何提取与ElasticSearch匹配的id的子集?
search = MyModel.search('query')
search.total_results # => 81
search.records.count # => 10
但我需要获得所有81个ID以便我可以执行一些统计(即汇总公司名称,我已经有一些代码可以工作,但现在我只得到前10个结果汇总...)
答案 0 :(得分:0)
好的,这是我目前的解决方案(我不喜欢,因为它击中了数据库很多)
仅使用MongoDB命名范围来过滤记录,并拔出其ID
ids = @my_model_filtered.pluck(:id)
将结果ID发送给ES,并使用特定字段的提升进行评分搜索
def search_by_id(query, type, ids, options = {})
self.weighted_search(query, options.deep_merge({
query: {
filtered: {
filter: {
ids: {
values: ids.map(&:to_s)
}.tap do |filter|
filter[:type] = type if type
end
}
}
}
}))
end
def weighted_search(query, options = {})
self.__elasticsearch__.search(
{
query: {
filtered: {
query: {
multi_match: {
query: query,
fields: [
"company_name^3",
"job_name^2",
"xxx"
],
type: "most_fields"
}
}
}
}
}.deep_merge(options)
)
end
使用Elasticsearch提供的ID列表对MongoDB数据库进行其他信息提取(聚合等)
@response = @searching.search_by_id(@query, @searchable_type, ids).per(10000) # setting a high per number so ES returns all IDs
@all_records = @response.records.records
# Further processing
@all_records.map_reduce(...)