![](/img/trans.png)
[英]Combine multiple individual queries into one to get aggregated result in Elasticsearch
[英]Elasticsearch paginating a sorted, aggregated result
據我所知,沒有辦法在Elasticsearch中執行以下操作:
SELECT * FROM myindex
GROUP BY agg_field1, agg_field2, agg_field3 // aggregation
ORDER BY order_field1, order_field2, order_field3 // sort
LIMIT 1000, 5000 // paginate -- get page 6 of size 1000 records
以下是一些有關此問題的相關文件:
有沒有辦法在Elasticsearch中執行上述操作? 我們的一個限制是我們永遠不會有超過10M的記錄,所以我們(希望)不應該遇到內存錯誤。 我的想法是這樣做:
實現這一目標的最佳方法是什么? 在您的回答/建議中,您能否發布一些有關如何在ES中完成上述SQL查詢的示例代碼?
作為此問題的更新,這是一個公共索引,用於測試:
# 5.6
e=Elasticsearch('https://search-testinges-fekocjpedql2f3rneuagyukvy4.us-west-1.es.amazonaws.com')
e.search('testindex')
# 6.4 (same data as above)
e = Elasticsearch('https://search-testinges6-fycj5kjd7l5uyo6npycuashch4.us-west-1.es.amazonaws.com')
e.search('testindex6')
它有10,000條記錄。 隨意測試:
我正在尋找的查詢如下(在sql中):
SELECT * FROM testindex
GROUP BY store_url, status, title
ORDER BY title ASC, status DESC
LIMIT 100 OFFSET 6000
換句話說,我希望對聚合結果(具有多個聚合)進行排序並獲得偏移量。
composite
聚合可能在這里有所幫助,因為它允許您按多個字段進行分組,然后對結果進行分頁。 它不允許你做的唯一事情就是跳過一個給定的偏移量,但你可以通過從客戶端代碼迭代來做到這一點,如果有必要的話。
所以這是一個示例查詢:
POST testindex6/_search
{
"size": 0,
"aggs": {
"my_buckets": {
"composite": {
"size": 100,
"sources": [
{
"store": {
"terms": {
"field": "store_url"
}
}
},
{
"status": {
"terms": {
"field": "status",
"order": "desc"
}
}
},
{
"title": {
"terms": {
"field": "title",
"order": "asc"
}
}
}
]
},
"aggs": {
"hits": {
"top_hits": {
"size": 100
}
}
}
}
}
}
在響應中你會看到和after_key
結構:
"after_key": {
"store": "http://google.com1087",
"status": "OK1087",
"title": "Titanic1087"
},
這是您需要在后續查詢中使用的某種游標,如下所示:
{
"size": 0,
"aggs": {
"my_buckets": {
"composite": {
"size": 100,
"sources": [
{
"store": {
"terms": {
"field": "store_url"
}
}
},
{
"status": {
"terms": {
"field": "status",
"order": "desc"
}
}
},
{
"title": {
"terms": {
"field": "title",
"order": "asc"
}
}
}
],
"after": {
"store": "http://google.com1087",
"status": "OK1087",
"title": "Titanic1087"
}
},
"aggs": {
"hits": {
"top_hits": {
"size": 100
}
}
}
}
}
}
它將為您提供接下來的100個桶。 希望這會有所幫助。
更新 :
如果你想知道總共會有多少桶,那么composite
聚合將不會給你這個數字。 但是,由於composite
聚合只不過是其來源中所有字段的笛卡爾積,您可以通過返回]基數]來獲得該總數的良好近似值( https://www.elastic.co/guide /en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html ) composite
聚合中使用的每個字段並將它們相乘。
"aggs": {
"my_buckets": {
"composite": {
...
}
},
"store_cardinality": {
"cardinality": {
"field": "store_url"
}
},
"status_cardinality": {
"cardinality": {
"field": "status"
}
},
"title_cardinality": {
"cardinality": {
"field": "title"
}
}
}
然后我們可以通過將store_cardinality
, status_cardinality
和title_cardinality
的數字相乘,或者至少得到一個很好的近似值來得到桶的總數(它在高基數字段上不能很好地工作,但在低基數上很好那些)。
現場崩潰就是答案。
當我們想要在特定字段上對命中進行分組時(如在agg_field中的組中),將使用字段折疊功能。
在Elastic 6之前,對字段進行分組的方法是使用聚合 。 這種方法缺乏高效分頁的能力。
但是現在,通過彈性提供開箱即用的場地坍塌,這很容易。
以下是從上面的鏈接獲取字段折疊的示例查詢。
GET /twitter/_search
{
"query": {
"match": {
"message": "elasticsearch"
}
},
"collapse" : {
"field" : "user",
"inner_hits": {
"name": "last_tweets",
"size": 5,
"sort": [{ "date": "asc" }]
},
"max_concurrent_group_searches": 4
},
"sort": ["likes"]
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.