2015-09-05 162 views
6

對於ElasticSearch而言,我只有短短几天的時間,並且學習練習已經實現了一個基本作業刮除器,它從幾個作業列表站點彙總作業,並用一些數據填充索引給我玩。ElasticSearch中已過濾的嵌套inner_hits查詢的聚合

我的索引包含列出作業的每個網站的文檔。這些文檔中的每個文檔的屬性都是'jobs'數組,其中包含該網站上存在的每個作業的對象。我正在考慮將每個作業索引爲自己的文檔(尤其是因爲ElasticSearch文檔說inner_hits是一個實驗性功能),但現在我正在嘗試使用ElasticSearch的inner_hits和嵌套功能來實現我想要的功能。

我能夠查詢,篩選並返回只匹配的作業。但是,我不確定如何將相同的inner_hits約束應用於聚合。

這是我的映射:

{ 
    "jobsitesIdx" : { 
    "mappings" : { 
     "sites" : { 
     "properties" : { 
      "createdAt" : { 
      "type" : "date", 
      "format" : "dateOptionalTime" 
      }, 
      "jobs" : { 
      "type" : "nested", 
      "properties" : { 
       "company" : { 
       "type" : "string" 
       }, 
       "engagement" : { 
       "type" : "string" 
       }, 
       "link" : { 
       "type" : "string", 
       "index" : "not_analyzed" 
       }, 
       "location" : { 
       "type" : "string", 
       "fields" : { 
        "raw" : { 
        "type" : "string", 
        "index" : "not_analyzed" 
        } 
       } 
       }, 
       "title" : { 
       "type" : "string" 
       } 
      } 
      }, 
      "jobscount" : { 
      "type" : "long" 
      }, 
      "sitename" : { 
      "type" : "string" 
      }, 
      "url" : { 
      "type" : "string" 
      } 
     } 
     } 
    } 
    } 
} 

這是一個查詢和彙總,我想(從Node.js的):

client.search({ 
    "index": 'jobsitesIdx, 
    "type": 'sites', 
    "body": { 


    "aggs" : { 
      "jobs" : { 
       "nested" : { 
        "path" : "jobs" 
       }, 
       "aggs" : { 
        "location" : { "terms" : { "field" : "jobs.location.raw", "size": 25 } }, 
        "company" : { "terms" : { "field" : "jobs.company.raw", "size": 25 } } 
       } 
      } 
     }, 


    "query": { 
     "filtered": { 
      "query": {"match_all": {}}, 
      "filter": { 
      "nested": { 
       "inner_hits" : { "size": 1000 }, 
       "path": "jobs", 
       "query":{ 
       "filtered": { 
        "query": { "match_all": {}}, 
        "filter": { 
        "and": [ 
         {"term": {"jobs.location": "york"}}, 
         {"term": {"jobs.location": "new"}} 
        ] 
        } 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
}, function (error, response) { 
    response.hits.hits.forEach(function(jobsite) { 
    jobs = jobsite.inner_hits.jobs.hits.hits; 

    jobs.forEach(function(job) { 
     console.log(job); 
    }); 

}); 

    console.log(response.aggregations.jobs.location.buckets); 
}); 

這給我回的新作業的所有inner_hits約克,但總計顯示我數量爲每個位置和公司,而不僅僅是匹配inner_hits。

有關如何僅獲取匹配inner_hits中包含的數據的聚合的任何建議?

編輯: 我正在更新它,以包括根據請求導出映射和索引數據。我出口這種使用Taskrabbit的elasticdump工具,在這裏找到: https://github.com/taskrabbit/elasticsearch-dump

指數:http://pastebin.com/WaZwBwn4 映射:http://pastebin.com/ZkGnYN94

從示例代碼中的上述鏈接數據的不同之處我原來的問題,該指數名爲jobsites6在數據中,而不是問題中提到的jobsitesIdx。此外,數據中的類型是「工作」,而在上面的代碼中是「網站」。

我在上面的代碼中填充了回調以顯示響應數據。我從inner_hits的foreach循環看到在紐約唯一的工作,符合市場預期,但我看到這個聚集的位置:

[ { key: 'New York, NY', doc_count: 243 }, 
    { key: 'San Francisco, CA', doc_count: 92 }, 
    { key: 'Chicago, IL', doc_count: 43 }, 
    { key: 'Boston, MA', doc_count: 39 }, 
    { key: 'Berlin, Germany', doc_count: 22 }, 
    { key: 'Seattle, WA', doc_count: 22 }, 
    { key: 'Los Angeles, CA', doc_count: 20 }, 
    { key: 'Austin, TX', doc_count: 18 }, 
    { key: 'Anywhere', doc_count: 16 }, 
    { key: 'Cupertino, CA', doc_count: 15 }, 
    { key: 'Washington D.C.', doc_count: 14 }, 
    { key: 'United States', doc_count: 11 }, 
    { key: 'Atlanta, GA', doc_count: 10 }, 
    { key: 'London, UK', doc_count: 10 }, 
    { key: 'Ulm, Deutschland', doc_count: 10 }, 
    { key: 'Riverton, UT', doc_count: 9 }, 
    { key: 'San Diego, CA', doc_count: 9 }, 
    { key: 'Charlotte, NC', doc_count: 8 }, 
    { key: 'Irvine, CA', doc_count: 8 }, 
    { key: 'London', doc_count: 8 }, 
    { key: 'San Mateo, CA', doc_count: 8 }, 
    { key: 'Boulder, CO', doc_count: 7 }, 
    { key: 'Houston, TX', doc_count: 7 }, 
    { key: 'Palo Alto, CA', doc_count: 7 }, 
    { key: 'Sydney, Australia', doc_count: 7 } ] 

由於我inner_hits僅限於在紐約,我可以看到,聚合不在我的inner_hits上,因爲它給我所有位置的計數。

+0

你能否提供一些示例數據(可能在要點或其他)?你期待的結果會被返回嗎? –

回答

10

您可以通過在聚合中添加相同的過濾器來僅實現紐約作業。 另請注意,在您的第二次聚合中,您有company.raw,但在您的映射中,jobs.company字段沒有not_analyzed部分名稱raw,因此如果要在未分析的公司名稱上進行聚合,您可能需要添加它。

{ 
    "_source": [ 
    "sitename" 
    ], 
    "query": { 
    "filtered": { 
     "filter": { 
     "nested": { 
      "inner_hits": { 
      "size": 1000 
      }, 
      "path": "jobs", 
      "query": { 
      "filtered": { 
       "filter": { 
       "terms": { 
        "jobs.location": [ 
        "new", 
        "york" 
        ] 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
    }, 
    "aggs": { 
    "jobs": { 
     "nested": { 
     "path": "jobs" 
     }, 
     "aggs": { 
     "only_loc": { 
      "filter": {   <----- add this filter 
      "terms": { 
       "jobs.location": [ 
       "new", 
       "york" 
       ] 
      } 
      }, 
      "aggs": { 
      "location": { 
       "terms": { 
       "field": "jobs.location.raw", 
       "size": 25 
       } 
      }, 
      "company": { 
       "terms": { 
       "field": "jobs.company", 
       "size": 25 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 
+0

我已確認此作品,謝謝!據我瞭解,由'查詢'返回的父文件影響聚合的範圍;如果ES允許對inner_hits應用相同的內容,而不必在aggs中再次重複該過濾器的約束,那將會很好。另一方面,也許使用「實驗性」的inner_hits功能會引起麻煩。另外,我還記得自己添加jobs.company.raw下一次我重新創建索引,很好的捕獲。 – mmccaff