[Elasticsearch] 控制相關度 (六) - function_score查詢中的filter,functions及random_score參數


本章翻譯自Elasticsearch官方指南的Looking at Time一章。


時間數據處理(Looking at Time)

如果在ES中,搜索是最常見的行為,那么創建日期柱狀圖(Date Histogram)肯定是第二常見的。為什么要使用日期柱狀圖呢?

想象在你的數據中有一個時間戳。數據是什么不重要-Apache日志事件,股票交易日期,棒球比賽時間-任何擁有時間戳的數據都能通過日期柱狀圖受益。當你有時間戳時,你經常會想創建基於時間的指標信息:

  • 今年的每個月銷售了多少輛車?

  • 過去的12小時中,這只股票的價格是多少?

  • 上周每個小時我們的網站的平均延遲是多少?

常規的histogram通常使用條形圖來表示,而date histogram傾向於被裝換為線圖(Line Graph)來表達時間序列(Time Series)。很多公司使用ES就是為了對時間序列數據進行分析。

date_histogram的工作方式和常規的histogram類似。常規的histogram是基於數值字段來創建數值區間的桶,而date_histogram則是基於時間區間來創建桶。因此每個桶是按照某個特定的日歷時間定義的(比如,1個月或者是2.5天)。

常規Histogram能夠和日期一起使用嗎?

從技術上而言,是可以的。常規的histogram桶可以和日期一起使用。但是,它並懂日期相關的信息(Not calendar-aware)。而對於date_histogram,你可以將間隔(Interval)指定為1個月,它知道2月份比12月份要短。date_histogram還能夠和時區一同工作,因此你可以根據用戶的時區來對圖形進行定制,而不是根據服務器。

常規的histogram會將日期理解為數值,這意味着你必須將間隔以毫秒的形式指定。同時聚合也不理解日歷間隔,所以它對於日期幾乎是沒法使用的。

第一個例子中,我們會創建一個簡單的線圖(Line Chart)來回答這個問題:每個月銷售了多少輛車?

GET /cars/transactions/_search?search_type=count
{
   "aggs": { "sales": { "date_histogram": { "field": "sold", "interval": "month", "format": "yyyy-MM-dd" } } } }

在查詢中有一個聚合,它為每個月創建了一個桶。它能夠告訴我們每個月銷售了多少輛車。同時指定了一個額外的格式參數讓桶擁有更"美觀"的鍵值。在內部,日期被簡單地表示成數值。然而這會讓UI設計師生氣,因此使用格式參數可以讓日期以更常見的格式進行表示。

得到的響應符合預期,但是也有一點意外(看看你能夠察覺到):

{
   ...
   "aggregations": { "sales": { "buckets": [ { "key_as_string": "2014-01-01", "key": 1388534400000, "doc_count": 1 }, { "key_as_string": "2014-02-01", "key": 1391212800000, "doc_count": 1 }, { "key_as_string": "2014-05-01", "key": 1398902400000, "doc_count": 1 }, { "key_as_string": "2014-07-01", "key": 1404172800000, "doc_count": 1 }, { "key_as_string": "2014-08-01", "key": 1406851200000, "doc_count": 1 }, { "key_as_string": "2014-10-01", "key": 1412121600000, "doc_count": 1 }, { "key_as_string": "2014-11-01", "key": 1414800000000, "doc_count": 2 } ] ... }

聚合完整地被表達出來了。你能看到其中有用來表示月份的桶,每個桶中的文檔數量,以及漂亮的key_as_string。


 

返回空桶

發現在上面的響應中的奇怪之處了嗎?

Yep, that’s right. We are missing a few months! By default, the date_histogram (and histogram too) returns only buckets that have a nonzero document count. 是的,我們缺失了幾個月!默認情況下,date_histogram(以及histogram)只會返回文檔數量大於0的桶。

這意味着得到的histogram響應是最小的。但是有些時候該行為並不是我們想要的。對於很多應用而言,你需要將得到的響應直接置入到一個圖形庫中,而不需要任何額外的處理。

因此本質上,我們需要返回所有的桶,哪怕其中不含有任何文檔。我們可以設置兩個額外的參數來實現這一行為:

GET /cars/transactions/_search?search_type=count
{
   "aggs": { "sales": { "date_histogram": { "field": "sold", "interval": "month", "format": "yyyy-MM-dd", "min_doc_count" : 0, "extended_bounds" : { "min" : "2014-01-01", "max" : "2014-12-31" } } } } }

以上的min_doc_count參數會強制返回空桶,extended_bounds參數會強制返回一整年的數據。

這兩個參數會強制返回該年中的所有月份,無論它們的文檔數量是多少。min_doc_count的意思很容易懂:它強制返回哪怕為空的桶。

extended_bounds參數需要一些解釋。min_doc_count會強制返回空桶,但是默認ES只會返回在你的數據中的最小值和最大值之間的桶。

因此如果你的數據分布在四月到七月,你得到的桶只會表示四月到七月中的幾個月(可能為空,如果使用了min_doc_count=0)。為了得到一整年的桶,我們需要告訴ES需要得到的桶的范圍。

extended_bounds參數就是用來告訴ES這一范圍的。一旦你添加了這兩個設置,得到的響應就很容易被圖形生成庫處理而最終得到下圖:


 

另外的例子

我們已經看到過很多次,為了實現更復雜的行為,桶可以嵌套在桶中。為了說明這一點,我們會創建一個用來顯示每個季度,所有制造商的總銷售額的聚合。同時,我們也會在每個季度為每個制造商單獨計算其總銷售額,因此我們能夠知道哪種汽車創造的收益最多:

GET /cars/transactions/_search?search_type=count
{
   "aggs": { "sales": { "date_histogram": { "field": "sold", "interval": "quarter", "format": "yyyy-MM-dd", "min_doc_count" : 0, "extended_bounds" : { "min" : "2014-01-01", "max" : "2014-12-31" } }, "aggs": { "per_make_sum": { "terms": { "field": "make" }, "aggs": { "sum_price": { "sum": { "field": "price" } } } }, "total_sum": { "sum": { "field": "price" } } } } } }

可以發現,interval參數被設成了quarter。

得到的響應如下(刪除了很多):

{
....
"aggregations": { "sales": { "buckets": [ { "key_as_string": "2014-01-01", "key": 1388534400000, "doc_count": 2, "total_sum": { "value": 105000 }, "per_make_sum": { "buckets": [ { "key": "bmw", "doc_count": 1, "sum_price": { "value": 80000 } }, { "key": "ford", "doc_count": 1, "sum_price": { "value": 25000 } } ] } }, ... }

我們可以將該響應放入到一個圖形中,使用一個線圖(Line Chart)來表達總銷售額,一個條形圖來顯示每個制造商的銷售額(每個季度),如下所示:

 

無限的可能性

顯然它們都是簡單的例子,但是在對聚合進行繪圖時,是存在無限的可能性的。比如,下圖是Kibana中的一個用來進行實時分析的儀表板,它使用了很多聚合:

因為聚合的實時性,類似這樣的儀表板是很容易進行查詢,操作和交互的。這讓它們非常適合非技術人員和分析人員對數據進行分析,而不需要他們創建一個Hadoop任務。

為了創建類似Kibana的強大儀表板,你需要掌握一些高級概念,比如作用域(Scoping),過濾(Filtering)和聚合排序(Sorting Aggregations)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM