2016-09-22 44 views
0

我的索引中包含很多文件,他們每個人都有多個版本,例如:獲取最新的文檔版本和彙總結果

{"doc_id": 13, 
"version": 1, 
"text": "bar"} 

{"doc_id": 13, 
"version": 2, 
"text": "bar"} 

{"doc_id": 13, 
"version": 3, 
"text": "bar"} 

{"doc_id": 14, 
"version": 1, 
"text": "foo"} 

{"doc_id": 14, 
"version": 2, 
"text": "bar"} 

我想每個文檔的最後一個版本,並彙總他們(最後的版本)使用terms聚合。
我試着使用top hits檢索最後的版本:

{"size" :0, 
"aggs" : { 
    "doc_id_groups" : { 
     "terms" : { 
      "field" : "doc_id", 
      "size" : "0" 
     }, 
     "aggs" : { 
      "docs" : { 
       "top_hits" : { 
        "size" : 1, 
        "sort" : { 
         "version" : { 
          "order" : "desc" 
         } 
        } 
       } 
      } 
     } 
    } 
} 
} 

但我不能做聚合,因爲top hits不支持子聚合。
我猜測檢索ID然後聚合他們將是非常沉重的客戶端操作。
也許腳本可以幫助嗎?

更新:一件事我忘了提:聚合前的文件按時間範圍過濾,所以我們不知道哪個版本是在索引時間最近,僅在搜索時

+0

鑑於上述示例文檔,您期待什麼結果? – jay

+0

@jay我已經編輯了一些例子。我期待這樣的事情:''水桶「:[ { 」key「:」bar「, 」doc_count「:2 }]' –

+0

您是否需要一次完成這項工作,可以創建一個輔助索引來執行你所需要的嗎? – Val

回答

1

從提供的樣本和chat中的其他詳細信息,我不認爲您可以使用聚合獲得所需的結果。但是我可以提出一個替代的解決方案,而不是:

  1. 添加屬性「當前布爾類型這 將被設置爲true文件的所有最新版本的。如果 新版本插入 - 「當前」將在一箇舊版本設置爲 和較新的一個設置爲true。
  2. 添加屬性「時間點」將包含多個值。在當天結束時(任何其他期間都可以使用)所有 當前記錄將當前時間戳(或 期間的任何其他標識,例如「09.30.2016」或「Jan」)添加到「timepoints「 array。

優點

  • 您可以輕鬆地在某個時間點只是檢查的時間點是否是「時間點」數組中檢索當前記錄。

  • 您可以使用單個查詢檢索所有文檔中的所有可用時間點。

  • 您可以按時間點進行聚合。在每個時間點統計所有記錄。

  • 不需要維護多個索引,記錄的重複等,該算法非常簡單。

缺點

  • 沒有可能獲得的當前版本在任意時間點,當進行計算只是那些。

  • 如果您經常運行計算並且您擁有數百萬條記錄,則「時間點」數組的總體大小可能會顯着增加。

解決方法

  • 對於更細粒度的統計運行以小時爲單位計算。但是,一天(或一個月或一年)從較早時間段的「時間點」陣列中刪除一些時間點。最後,你將有一組時間點,對應於每一年(如果是一年多前),每個月(如果它是一個多月前),每天(如果它是超過一天前),並在最近一段時間每小時。當然,根據您的需要可以改進刪除時間點的算法。

  • 如果您主要使用最新版本的記錄 - 將它們存儲在單獨的索引中,請將舊版本存儲在另一個索引中。在這種情況下,您甚至不需要「當前」屬性,只需遍歷當前索引中的所有記錄並添加時間戳即可。

我可以在需要的情況下爲您提供上述步驟所需的所有查詢。

+0

偉大的解決方案!謝謝! –

0

你應該看看解決這個客戶端。我可以想出兩種方法來處理它。

  1. 使用scroll api瀏覽所有文檔並找到每個文檔的最新版本。然後再次客戶端,彙總由text
  2. doc_id上使用彈性搜索術語聚合,並在version上使用max aggregation的subaggregation。這將爲您提供每個文檔ID的最新版本。然後創建一個使用第一部分的doc_id和版本的布爾或術語過濾器。這個過濾器應該在text上有一個術語彙總。

無論哪種方式,您都需要做一些客戶端工作。我不相信腳本會幫助。如果您已經知道每個文檔的最新版本號,那麼這會更容易。

+0

如果我正確理解您的答案,每個解決方案都需要在客戶端存儲所有最新版本的ID,然後再將它們發送到聚合。由於大量的數據,這是不可能的。 –

+0

你有多少份文件?爲什麼你需要保留文檔的舊版本?或者,當您添加新版本時,您可以將舊版本移至不同的索引。另一個想法是在最新版本上有一個標誌,這樣你可以通過這個'isNewest'字段進行過濾,但是必須對新版本進行索引並更新舊版本 - 進行2次reindex操作。 – Phil

+0

請參閱我們與Val的討論http://chat.stackoverflow.com/rooms/124396/discussion-between-taras-kohut-and-val –