我一直在嘗試找出一種方法來對 Elasticsearch 中的術語聚合結果進行分頁,但到目前為止我還無法達到預期的結果。這是我試圖解決的問題。在我的索引中,我有一堆文檔,它們的分數(與 ES _score 分開)是根據文檔中其他字段的值計算的。每個文檔“屬于”一個客戶,由customer_id字段引用。該文檔還有一個 id,由doc_id字段引用,與 ES 元字段_id相同。這是一個例子。{ '_id': '1', 'doc_id': '1', 'doc_score': '85', 'customer_id': '123'}對于每個customer_id都有多個文檔,所有文檔都有不同的文檔 id 和不同的分數。我想要做的是,給定客戶 ID 列表,返回每個 customer_id 的頂級文檔(每個客戶僅 1 個),并能夠通過常規 ES 搜索 API 中的方法對類似于size的結果進行分頁。我想要用于文檔分數的字段是doc_score字段。到目前為止,在我當前的Python腳本中,我嘗試過使用具有“熱門命中”聚合的嵌套 aggs 來僅獲取每個客戶的頂級文檔。{ "size": 0, "query:": { "bool": { "must": [ { "match_all": {} }, { "terms": { "customer_id": customer_ids # a list of the customer ids I want documents for } }, { "exists": { "field": "score" # sometimes it's possible a document does not have a score } } ] } } "aggs": { "customers": { "terms" : { {"field": "customer_id", "min_doc_count": 1}, "aggs": { "top_documents": { "top_hits": { "sort": [ {"score": {"order": "desc"}} ], "size": 1 } } } } } }}然后,我通過遍歷每個客戶存儲桶來“分頁”,將頂部文檔 blob 附加到列表中,然后根據分數字段的值對列表進行排序,最后獲取切片documents_list[from:from+size]。問題是,假設我的列表中有 500 個客戶,但我只想要第二個 20 個文檔,即size = 20, from=20。因此,每次調用該函數時,我都必須首先獲取 500 個客戶中每個客戶的列表,然后進行切片。這聽起來效率很低,而且也是一個速度問題,因為我需要該函數盡可能快。理想情況下,我可以直接從 ES 獲取第二個 20,而無需在函數中進行任何切片。我已經研究了 ES 提供的復合聚合,但在我看來,我無法在我的情況下使用它,因為我需要獲取整個文檔,即常規搜索 API 響應中 _source 字段中的所有內容。我將非常感謝任何建議。
1 回答

大話西游666
TA貢獻1817條經驗 獲得超14個贊
最好的方法是使用分區
根據文檔:
GET /_search
{
? ?"size": 0,
? ?"aggs": {
? ? ? "expired_sessions": {
? ? ? ? ?"terms": {
? ? ? ? ? ? "field": "account_id",
? ? ? ? ? ? "include": {
? ? ? ? ? ? ? ?"partition": 1,
? ? ? ? ? ? ? ?"num_partitions": 25
? ? ? ? ? ? },
? ? ? ? ? ? "size": 20,
? ? ? ? ? ? "order": {
? ? ? ? ? ? ? ?"last_access": "asc"
? ? ? ? ? ? }
? ? ? ? ?},
? ? ? ? ?"aggs": {
? ? ? ? ? ? "last_access": {
? ? ? ? ? ? ? ?"max": {
? ? ? ? ? ? ? ? ? "field": "access_date"
? ? ? ? ? ? ? ?}
? ? ? ? ? ? }
? ? ? ? ?}
? ? ? }
? ?}
}
添加回答
舉報
0/150
提交
取消