2016-06-08 24 views
1

考虑下面的模型Rails和Elasticsearch - 过滤器,权重和统计

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 
  • 我需要non_retired
  • 过滤/做命名的搜索查询,如过滤器,我需要权重的某些字段(例如,给一些领域的重要性提高3倍)
  • 我需要根据总计结果(即不仅仅是前10个分页结果)得到统计数据,例如,汇总company_names(我已经在代码工作了,但我在获得“总计”结果ID时遇到问题。

我已经把所有一起的问题。从Rails elasticsearch - named scope search我了解到我需要直接向Elasticsearch提供ID。

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 

这是产生错误请求错误在以下的说明

[400] { “错误”:{ “ROOT_CAUSE”:[{ “类型”: “query_parsing_exception”, “理由”: “[赛事]查询不支持[$ OID]

我不明白这个错误......我不能IDS过滤??

然后,假设我有这个工作,我如何提取与ElasticSearch相匹配的id的子集?

search = MyModel.search('query') 
search.total_results # => 81 
search.records.count # => 10 

但我需要得到所有81个IDS这样我就可以执行一些统计数据(即聚合的公司名称,我已经有一些代码的工作,但现在我只得到了前10个结果汇总... )

回答

0

好吧,这是我目前的解决方案(我不喜欢,因为它击中的DB很多)

  • 只能使用MongoDB的命名范围以过滤记录和勇敢,他们的IDS

    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 
    
  • MongoDB的数据库提供的ID列表上做的更多信息抽取(聚合等)通过Elasticsearch

    @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(...)