据我所知,在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中是否可以执行上述操作?我们的一个限制是我们记录永远不会超过1000万,因此(希望)我们不应该遇到内存错误。我的想法是这样做:
实现此目标的最佳方法是什么?在您的回答/建议中,您能否发布一些示例代码,这些代码与如何在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
换句话说,我正在寻找一个汇总结果(具有多个汇总)并获得偏移量。
答案 0 :(得分:2)
composite
aggregation在这里可能会有所帮助,因为它允许您按多个字段分组,然后对结果进行分页。唯一不允许您执行的操作是跳转到给定的偏移量,但是您可以通过在必要时从客户端代码进行迭代来做到这一点。
因此,这是一个示例查询:
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
中获得的数字相乘,或者至少乘以good approximation thereof(得出在高基数字段上效果不佳,但在低基数字段上效果很好。
答案 1 :(得分:0)
Field collapsing是答案。
当我们要对特定字段上的匹配分组时使用字段折叠功能(如按agg_field分组)。
在Elastic 6之前,将字段分组的方法是use aggregation。这种方法缺乏进行有效寻呼的能力。
但是现在,由于弹性提供了开箱即用的电场塌陷,这非常容易。
下面是一个示例查询,其中字段折叠来自上方链接。
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"]
}