ES分页查询的最佳实践:三种方案

Elasticsearch(ES)中进行分页查询时,最佳实践取决于具体的使用场景和需求。
以下是对每种分页方法的简要分析以及它们适用的情况:
在这里插入图片描述

1. From + Size

  • 最常见且直观的方法,通过from参数指定跳过多少条记录,size参数指定每次返回多少条记录。
  • 优点:实现简单,适用于小规模或浅层分页,即前几页查询。
  • 缺点:随着from值增大,查询效率会显著降低,尤其是在深度分页的情况下(例如,查询很多页之后的数据),因为ES需要遍历所有之前的结果才能找到指定偏移的结果集,这对分布式系统来说成本非常高。

2. Scroll API

  • 提供了一种持续检索大量数据的方式,创建一个“滚动”上下文,可以在一段时间内保持一致性视图。
  • 优点:非常适合大数据量的批量读取或深度分页,尤其是在不需要考虑数据实时更新的情况下,如数据导出或批处理任务。
  • 缺点:滚动上下文会占用服务器资源,且对实时性要求高的场景不合适,因为它反映的是某个时间点的快照状态,不能反映出滚动上下文创建后数据的变化。

3. Search After

  • 从ES 5.0版本开始提供,用于克服from+size在深度分页时的性能瓶颈。
  • 优点:利用 _score 或用户定义的排序字段来进行连续查询,避免了大规模跳跃式分页的问题。相比from+size,它在深度分页时性能更优,同时能够更好地处理实时变化的数据。
  • 缺点:需要有稳定的排序字段,并且不是所有场景下都能方便地转换为search_after模式。

代码示例

package org.example;

import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class ESScrollMain {
    private static final String indexName = "kibana_sample_data_logs";

    public static void main(String[] args) throws IOException {
        System.out.println("Hello and welcome!");
        RestClientBuilder builder = RestClient.builder(new HttpHost("10.x.x.x", 9200, "http"));
        RestHighLevelClient client = new RestHighLevelClient(builder);

        SearchRequest searchRequest = new SearchRequest(indexName);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // hit 返回值(bool 查询返回条数)
//        searchSourceBuilder.size(0);
//        searchSourceBuilder.from(0);
        searchSourceBuilder.trackTotalHits(true);
        // 超时时间60s
        MatchAllQueryBuilder search = QueryBuilders.matchAllQuery();
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchSourceBuilder.size(2000);
        searchSourceBuilder.query(search);

        long scrollTime = 30L;
        searchRequest.source(searchSourceBuilder);
        searchRequest.scroll(TimeValue.timeValueSeconds(scrollTime));

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        String scrollId = searchResponse.getScrollId();
        SearchHit[] hits = searchResponse.getHits().getHits();

        int count = 0;
        int batch = 1;
        System.out.println("初始结果条数:" + count);
        count += hits.length;
        System.out.println("滚动第" + batch + "批结果总条数:" + count);
        while (hits != null && hits.length > 0) {
            batch++;
            SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);
            scrollRequest.scroll(TimeValue.timeValueSeconds(scrollTime));
            searchResponse = client.scroll(scrollRequest, RequestOptions.DEFAULT);
            scrollId = searchResponse.getScrollId();
            hits = searchResponse.getHits().getHits();
            count += hits.length;
            System.out.println("滚动第" + batch + "批结果总条数:" + count);

        }

        System.out.println("结束,总计:"+searchResponse.getHits().getTotalHits());

    }
}

综合考虑

  • 对于网页应用中的普通分页浏览,尤其是前几页,from+size足够。
  • 如果需要处理大数据集且允许一定的延迟,或者一次性获取所有结果,Scroll API 是更好的选择。
  • 对于深度分页且需要实时性较好的场景,应优先考虑search_after

优化方向

此外,针对大型分页查询的性能优化还可以包括:

  • 使用高效的过滤条件减少不必要的查询范围。
  • 考虑是否真的需要返回全部数据,或者能否通过汇总统计或其他方式减少数据传输量。
  • 设置合理的索引策略和分片大小,优化集群配置,如增加合适的内存缓冲区等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/446927.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Autosar Crypto Driver学习笔记(一)

文章目录 Crypto DriverPre-ConfigurationCryptographic capabilities加密能力Available Keys可用密钥 General BehaviorNormal OperationFunctional RequirementsSynchronous Job ProcessingAsynchronous Job Processing Design NotesPriority-dependent Job Queue基于优先级的…

docker安装jenkins并实现CICD流程

docker安装jenkins并实现CICD流程 本文目录 docker安装jenkins并实现CICD流程安装命令初始化设置更新jenkins及插件更新jenkins版本更新插件 创建第一个任务修改配置插件更新中心时区设置 安装命令 官方安装参考:https://www.jenkins.io/zh/doc/book/installing/ …

Docker安装tomcat

目录 一、安装Docker 二、Docker安装tomcat 三、安装tomcat 一、安装Docker 安装docker阅读 Docker整理之安装(1)-CSDN博客https://blog.csdn.net/ywanju/article/details/135442406 二、Docker安装tomcat 本案例安装的tomcat最新版本 搜(dockerhub搜索镜像版本) 拉(拉…

十二要素应用: 云原生应用最佳实践

本文介绍了开发部署云原生应用的一套最佳实践,通过这套最佳实践,可以最大限度利用云原生的能力,创建灵活、健壮、易管理的现代云原生应用程序。原文: The Twelve-Factor App: Best Practices for Cloud-Native Applications[1] 导言 软件如今…

爬虫与DataFrame对象小小结合

import pandas as pd import requests from lxml import etree #数据请求 url"https://www.maigoo.com/brand/list_1715.html" headers{User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5735.289 Safari…

【实验报告】C语言实现猜单词的小游戏

之前帮别人写的一个简单的报告,无偿分享给大家~代码在后面,有一些图片出于懒惰没有上传。比较简单,喜欢的话关注我~,请勿商用~ 1 系统功能模块结构图 该程序主要思路: 头文件设计,存储结构设计&#xff0…

Jmeter+Ant+Git/SVN+Jenkins实现持续集成接口测试,一文精通(一)

前言 Jmeter,Postman一些基本大家相比都懂。那么真实在项目中去使用,又是如何使用的呢?本文将一文详解jmeter接口测试 一、接口测试分类 二、目前接口架构设计 三、市面上的接口测试工具 四、Jmeter简介,安装,环境…

计算机网络—OSPF单区域配置

目录 目录 1.实验环境准备 2.配置 OSPF 3.验证 OSPF 配置 4.修改 OSPF hello 和 dead 时间参数 5.OSPF缺省路由发布及验证 6.控制 OSPF DR/BDR 的选举 7.配置文件 拓扑图&#xff1a; 1.实验环境准备 基本配置以及IP编址。 <Huawei>system-view Enter system vi…

YOLOv8改进 | 注意力篇 | 利用YOLO-Face提出的SEAM注意力机制优化物体遮挡检测(附代码 + 修改教程)

一、本文介绍 本文给大家带来的改进机制是由YOLO-Face提出能够改善物体遮挡检测的注意力机制SEAM&#xff0c;SEAM&#xff08;Spatially Enhanced Attention Module&#xff09;注意力网络模块旨在补偿被遮挡面部的响应损失&#xff0c;通过增强未遮挡面部的响应来实现这一目…

【JAVA】CSS定位与CSS3属性、渐变、CSS3字体、2D变换

1 定位 1.1 相对定位 相对定位没有脱离文档流 定位元素的显示层级比普通元素高 定位元素可以通过margin&#xff0c;float调整位置&#xff0c;但不推荐 包含块&#xff1a;父元素 left和right同时写&#xff0c;右失效 上下同时写&#xff0c;下失效 <head><s…

从零学习Linux操作系统 第三十四部分 Ansible中的执行流控制

一、ansible中的迭代循环 循环迭代任务# 1、简单循环# loop: ##赋值列表 – value1 – value2 – … {{item}} 迭代变量名称 2、循环散列或字典列表 二、Ansible中的条件语句 when: 条件1条件2 条件判断 ‘’value “字符串”,value 数字‘<’value < 数字‘>…

【基础计算机网络2】物理层——通信基础

【前言回顾】 【考纲内容】 一、物理层的基本概念 1.1 物理层的主要任务 物理层解决如何在连接各种计算机的传输媒体上传输数据比特流&#xff0c;而不是指具体的传输媒介。物理层的主要任务&#xff1a;确定与传输媒体接口有关的一些特性。 1.2 物理层的一些特性 机械特性…

C++变参模板

从c11开始&#xff0c;模板可以接受一组数量可变的参数&#xff0c;这种技术称为变参模板。 变参模板 下面一个例子&#xff0c;通过变参模板打印一组数量和类型都不确定的参数。 #include <iostream> #include <string>void print(void) {std::cout<<&quo…

【最新版】ChatGPT/GPT4科研应用与AI绘图论文写作(最新增加Claude3、Gemini、Sora、GPTs技术及AI领域中的集中大模型的最新技术)

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

关于playbook中when条件过滤报The conditional check ‘result|failed‘ failed的问题

问题现象 在使用plabook中的when做过滤脚本如下&#xff1a; --- - hosts: realserversremote_user: roottasks:- name: Check if httpd service is runningcommand: systemctl status httpdregister: resultignore_errors: True- name: Handle failed service checkdebug:ms…

docker常用操作-docker私有仓库的搭建(Harbor),并将本地镜像推送至远程仓库中。

1、docker-compose安装&#xff0c;下载docker-compose的最新版本 第一步&#xff1a;创建docker-compose空白存放文件vi /usr/local/bin/docker-compose 第二步&#xff1a;使用curl命令在线下载&#xff0c;并制定写入路径 curl -L "https://github.com/docker/compos…

基于Spring Boot + Vue的电影购票系统

基于Spring Boot Vue的电影购票系统 功能介绍 分为用户端和商家端&#xff0c;商家端只能让拥有商家角色的人登录 商家可以在系统上面注册自己家的影院信息选择影院进去管理&#xff0c;在选择完要进行操作的影院后&#xff0c;可以在系统的电影库选择电影为当前的影院进行电…

Docker容器Docker桌面配置镜像加速

打开Docker Desktop应用程序&#xff0c;点击设置 具体配置如下&#xff1a; {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"features": {"buil…

VScode(Python)使用ssh远程开发(Linux系统树莓派)时,配置falke8和yapf总结避坑!最详细,一步到位!

写在前面&#xff1a;在Windows系统下使用VScode时可以很舒服的使用flake8和yapf&#xff0c;但是在ssh远程开发树莓派时&#xff0c;我却用不了&#xff0c;总是出现问题。当时我就开始了漫长的探索求知之路。中间也请教过许多大佬&#xff0c;但是他们就讲“能用不就行了&…

Windows10/11配置WSL(Ubuntu)环境

文章目录 WSL介绍WSL部署扩展&#xff1a;辅助工具Windosw Terminal安装下载 WSL介绍 传统方式获取Linux操作系统&#xff0c;是安装完整的虚拟机及镜像环境&#xff0c;例如虚拟机VMware 而使用WSL,可以以非常轻量化的方式&#xff0c;得到Linux系统环境 它无需单独虚拟一套硬…