2016-06-08 25 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(...)