首页 > 解决方案 > 对按弹性索引上的命中排序的聚合进行分页

问题描述

我有一个弹性索引(比如file),每次客户端下载文件时,我都会在其中附加一个文档。每个文档都非常基本,它包含一个字段filename和一个日期,以指示下载时间。

我想要实现的是获取每个文件在过去 3 个月内下载的次数。感谢另一个问题,我有一个返回所有结果的查询:

{
    "query": {
        "range": {
            "when": {
                "gte": "now-3M"
            }
        }
    },
    "aggs": {
        "downloads": {
            "terms": {
                "field": "filename.keyword",
                "size": 1000
            }
        }
    },
    "size": 0
}

现在,我想要一个分页的结果。术语聚合不能分页,所以我使用复合聚合。当然,如果有更好的聚合,这里可以使用...

所以目前,我有这样的事情:

{
    "query": {
        "range": {
            "when": {
                "gte": "now-3M"
            }
        }
    },
    "aggs": {
        "downloads_agg": {
            "composite": {
                "size": 100,
                "sources": [
                    {
                        "downloads": {
                            "terms": {
                                "field": "filename.keyword"
                            }
                        }
                    }
                ]
            }
        }
    },
    "size": 0
}

这种聚合允许我进行分页(感谢after_key响应中的值),但它不按下载次数排序 - 它按文件名排序。

如何根据索引中每个文件名的文档数对复合聚合进行排序?

谢谢。

标签: elasticsearch

解决方案


复合聚合不允许基于值字段进行排序。

摘自弹性论坛的讨论:

它被设计为一种内存友好的方式来对聚合进行分页。部分权衡是您会丢失诸如按文档计数排序之类的东西,因为直到收集完所有文档后才知道这一点。


我没有使用Transforms(X-pack & Licensed 的一部分)的经验,但您可以尝试一下。除此之外,我看不到获得预期输出的方法。


推荐阅读