2016-11-17 153 views
1

我已經這樣在我ElasticSearch對象:Elasticsearch算術和嵌套聚集

"myobject": { 
    "type": "blah", 
    "events": [ 
    { 
     "code": "code1" 
     "date": "2016-08-03 18:00:00" 
    }, 
    { 
     "code": "code2" 
     "date": "2016-08-03 20:00:00" 
    } 
    ] 
} 

我想計算的平均時間花費在與代碼「代碼1」事件與事件之間有型「碼2 」。基本上,我需要從每個對象的「code1」日期中減去「code2」的日期,然後計算平均值。

感謝您的幫助!

+0

這不會像你想象的那麼容易。你要麼需要「事件」嵌套,然後你需要一些腳本聚合,我甚至不知道你可以做...你可以索引2個事件分開,而不是在一個數組? –

+0

嗨@DennisIch,「事件」數組在我的映射中聲明爲嵌套數組。我目前正在看看我可以通過腳本度量聚合來做什麼(https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-scripted-metric-aggregation.html)。我可以在地圖階段減去,然後在縮小階段做平均。作爲B計劃,我可以預先使用插入/更新腳本來計算日期差異。 –

+0

好的,這種方法運行良好,但數據增長時需要花費太多時間。所以正確的解決方案是預先計算這些值@Val建議波紋管。 –

回答

0

B計劃肯定好多了。你可以在索引時做任何事情,你應該這樣做。如果你知道你需要這個日期差異,那麼你應該在索引時計算它並將它存儲到另一個字段中。

你一定要不用擔心存儲冗餘數據,Elasticsearch並不在乎。在每個查詢過程中,您的羣集比存儲繁重的腳本更好。您的用戶也會很感激,因爲隨着數據的增長,他們不必等待很長時間才能得到答案。

因此存儲這個代替(time_spent是第二和第一事件之間的毫秒數):

"myobject": { 
    "type": "blah", 
    "time_spent": 7200000, 
    "events": [ 
    { 
     "code": "code1" 
     "date": "2016-08-03 18:00:00" 
    }, 
    { 
     "code": "code2" 
     "date": "2016-08-03 20:00:00" 
    } 
    ] 
} 

然後你就可以運行一個簡單的查詢聚集這樣的:

{ 
    "size": 0, 
    "aggs": { 
    "avg_duration": { 
     "avg": { 
     "field": "time_spent" 
     } 
    } 
    } 
} 
+0

儘管在插入時預先計算這些值是有一點限制的,但我認爲這是處理大量數據的正確方法。 Map/Reduce腳本只能在小數據集上工作。 –

+0

您不應該害怕在索引時重複數據,以便在搜索/聚合時更容易將其壓縮。你需要採用與RDBMS不同的思維方式。 – Val

+1

Val我重複數據沒有問題,尤其是當我非常瞭解數據如何被查詢時。這裏的問題是,如果需要新的查詢,我並不完全知道可能導致爲所有數據預先計算新值的所有查詢(BI)。 –