elasticsearch聚合结果分页查询

1、Elasticsearch支持聚合后分页吗,为什么?

不支持,看看Elasticsearch员工如何解读。
1)性能角度——聚合分页会在大量的记录中产生性能问题。
2)正确性角度——聚合的文档计数不准确。
所以奇怪的事情可能会发生,如第二页的第一项具有比第一页的最后一个元素更高的计数。

2、Elasticsearch要实现聚合后分页,该怎么办?

方案:需要展示满足条件的全部数据条数,即需要全量聚合,且按照某规则排序。
注意,如果你要聚合的数据量很大(十万、百万甚至千万级),这必然会很慢并且可能超时。

步骤1:全量聚合,size设置为最大值: 2147483647
ES5.X/6.X版本设置为2147483647 ,它等于2^31-1,
是32位操作系统中最大的符号型整型常量;ES1.X 2.X版本设置为0。

例如:

  "aggregations": {
    
    
    "statistics_assets": {
    
    
      "terms": {
    
    
        "field": "one_account.one_account_no",
        "size": 2147483647,
        "order": {
    
    
          "assets": "asc"
        }

      },
      "aggregations": {
    
    
        "assets": {
    
    
          "sum": {
    
    
            "field": "assets.merge"
          }
        }
      }
    }
  }

上面size设置为了最大值2147483647,因为聚合的结果只有几百或者几千(如果聚合的结果很多不能一次性返回考虑使用bucket_sort,下面会说到),我们聚合结果可以一次性返回后,可通过分页参数获取指定部分结果(Java可用list或LinkedHashMap存储,HashMap存入顺序可能会改变)

步骤2:将聚合结果存入内存中,使用Java可以考虑list或map存储。

步骤3:内存内分页,Java里对list中存储的数据进行分页返回行。
如每页10条数据,取第一页就是:取list中第0到第9个元素,以此类推。

总结:
这篇文章讲的方法是聚合数据量不大且聚合结果不是很多时,将聚合结果全部返回,然后java后端用list存储并分页。

缺点:
但是这个方法如果数据量过大,在es聚合的时候会超时也会很慢,并且如果产生的聚合结果很多的话一次性返回给java端也不行。如果你的聚合数据量不大,又不想将聚合的结果一次性返回,可以考虑采用bucket_sort,
例如:

"aggregations": {
    
    
    "statistics_assets": {
    
    
      "terms": {
    
    
        "field": "one_account.one_account_no",
        "size": 245645500
      },
      "aggregations": {
    
    
        "assets": {
    
    
          "sum": {
    
    
            "field": "assets.merge"
          }
        },
        "assets_bucket_sort": {
    
    
          "bucket_sort": {
    
    
            "sort": {
    
    
              "assets": {
    
    
                "order": "desc"
              }
            },
            "from": 0,
            "size": 10
          }
        }
      }
    }
  }

参考如下官方文档或文章:
Bucket sort aggregationedit
How to add Bucket Sort to Query Aggregation
Aggregation + sorting +pagination in elastic search

如果你的聚合数据量很大,使用bucket_sort也不行的话,建议让中台或数据部门es新加字段,数据重新进行处理计算,把要聚合的数据弄到新加的字段里,这样你就不用聚合了,只需要直接取该字段的值就行。

参考文章:
Elasticsearch聚合后分页深入详解

猜你喜欢

转载自blog.csdn.net/qq_33697094/article/details/109820792
今日推荐