如何在Elasticsearch中对术语聚合结果进行分页



我一直在试图找到一种方法,在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列表,返回每个客户id的顶部文档(每个客户仅1个(,并且能够对这些结果进行分页,类似于常规ES搜索API中的大小方法。我要用于文档评分的字段是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
}
}
}
}
}
}
}

然后我";paginate";通过遍历每个客户存储桶,将顶部文档blob附加到列表中,然后根据score字段的值对列表进行排序,最后取一个切片documents_list[from:from+size]

这样做的问题是,假设我的列表中有500个客户,但我只想要第二个20个文档,即size = 20from=20。因此,每次调用函数时,我都必须首先获得500个客户中每个客户的列表,然后进行切片。这听起来效率很低,也是一个速度问题,因为我需要这个功能尽可能快

理想情况下,我可以直接从ES获得第二个20,而不必在我的函数中进行任何切片。

我已经研究了ES提供的复合聚合,但在我看来,我无法在我的情况下使用它,因为我需要获取整个文档,即常规搜索API响应中_source字段中的所有内容。

如果有任何建议,我将不胜感激。

最好的方法是使用分区

根据文件:

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"
}
}
}
}
}
}

https://www.elastic.co/guide/en/elasticsearch/reference/6.8/search-aggregations-bucket-terms-aggregation.html#_filtering_values_with_partitions

最新更新