2017-09-24 97 views
1

我們在Elasticsearch中有一組日誌,每個組包含共享一個唯一ID(名爲transactionId)的1-7個日誌。每個組中的每個日誌都有一個唯一的時間戳(eventTimestamp)。用具有唯一ID的組返回具有最新時間戳的日誌

例如:

{ 
    "transactionId": "id111", 
    "eventTimestamp": "1505864112047", 
    "otherfieldA": "fieldAvalue", 
    "otherfieldB": "fieldBvalue" 
} 

{ 
    "transactionId": "id111", 
    "eventTimestamp": "1505864112051", 
    "otherfieldA": "fieldAvalue", 
    "otherfieldB": "fieldBvalue" 
} 

{ 
    "transactionId": "id222", 
    "eventTimestamp": "1505863719467", 
    "otherfieldA": "fieldAvalue", 
    "otherfieldB": "fieldBvalue" 
} 

{ 
    "transactionId": "id222", 
    "eventTimestamp": "1505863719478", 
    "otherfieldA": "fieldAvalue", 
    "otherfieldB": "fieldBvalue" 
} 

我需要編寫返回所有所有transactionIds的最新時間戳在一定日期範圍內的查詢。

我簡單的例子繼續,查詢的結果應該返回這些日誌:

{ 
    "transactionId": "id111", 
    "eventTimestamp": "1505864112051", 
    "otherfieldA": "fieldAvalue", 
    "otherfieldB": "fieldBvalue" 
} 

{ 
    "transactionId": "id222", 
    "eventTimestamp": "1505863719478", 
    "otherfieldA": "fieldAvalue", 
    "otherfieldB": "fieldBvalue" 
} 

如何建立,完成此查詢任何想法?

回答

1

您可以不通過查詢本身獲得所需結果,但可以使用terms aggregation和嵌套top hits aggregation的組合。

術語聚合負責構建桶,其中所有具有相同術語的項目都在同一個桶中。根據transactionId,這可以生成您的羣組。然後,頂級聚合聚合是一個度量聚合,可以根據給定的排序順序將其配置爲返回一個存儲桶的x頂點。這使您可以檢索每個存儲桶中時間戳最大的日誌事件。

假設你的樣本數據的默認映射(其中字符串索引爲thekey(文本)和thekey.keyword(非分析的文本))此查詢:

GET so-logs/_search 
{ 
    "size": 0, 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "range": { 
      "eventTimestamp.keyword": { 
       "gte": 1500000000000, 
       "lte": 1507000000000 
      } 
      } 
     } 
     ] 
    } 
    }, 
    "aggs": { 
    "by_transaction_id": { 
     "terms": { 
     "field": "transactionId.keyword", 
     "size": 10 
     }, 
     "aggs": { 
     "latest": { 
      "top_hits": { 
      "size": 1, 
      "sort": [ 
       { 
       "eventTimestamp.keyword": { 
        "order": "desc" 
       } 
       } 
      ] 
      } 
     } 
     } 
    } 
    } 
} 

會產生以下輸出:

{ 
    "took": 7, 
    "timed_out": false, 
    "_shards": { 
    "total": 5, 
    "successful": 5, 
    "failed": 0 
    }, 
    "hits": { 
    "total": 4, 
    "max_score": 0, 
    "hits": [] 
    }, 
    "aggregations": { 
    "by_transaction_id": { 
     "doc_count_error_upper_bound": 0, 
     "sum_other_doc_count": 0, 
     "buckets": [ 
     { 
      "key": "id111", 
      "doc_count": 2, 
      "latest": { 
      "hits": { 
       "total": 2, 
       "max_score": null, 
       "hits": [ 
       { 
        "_index": "so-logs", 
        "_type": "entry", 
        "_id": "AV6z9Yj4QYbhNp_FoXa1", 
        "_score": null, 
        "_source": { 
        "transactionId": "id111", 
        "eventTimestamp": "1505864112051", 
        "otherfieldA": "fieldAvalue", 
        "otherfieldB": "fieldBvalue" 
        }, 
        "sort": [ 
        "1505864112051" 
        ] 
       } 
       ] 
      } 
      } 
     }, 
     { 
      "key": "id222", 
      "doc_count": 2, 
      "latest": { 
      "hits": { 
       "total": 2, 
       "max_score": null, 
       "hits": [ 
       { 
        "_index": "so-logs", 
        "_type": "entry", 
        "_id": "AV6z9ZlOQYbhNp_FoXa4", 
        "_score": null, 
        "_source": { 
        "transactionId": "id222", 
        "eventTimestamp": "1505863719478", 
        "otherfieldA": "fieldAvalue", 
        "otherfieldB": "fieldBvalue" 
        }, 
        "sort": [ 
        "1505863719478" 
        ] 
       } 
       ] 
      } 
      } 
     } 
     ] 
    } 
    } 
} 

在這裏你可以找到聚集的內部預期的效果根據查詢中定義的聚合名稱結果by_transaction_id.latest

請注意,聚合條款對返回的桶數有限制,並且從性能的角度來看,將此設置爲> 10.000可能不是一個聰明的想法。詳情請參閱the section on size of the terms aggregation。如果你想處理大量不同的事務id,我建議按事務ID做一些冗餘的「top」條目存儲。

另外,您應該將eventTimestamp字段切換爲date以獲得更好的性能,a wider set of query possibilities

相關問題