Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >elasticsearch的分页查询的用法与分析

elasticsearch的分页查询的用法与分析

原创
作者头像
空洞的盒子
发布于 2023-11-21 06:17:35
发布于 2023-11-21 06:17:35
1.8K00
代码可运行
举报
文章被收录于专栏:JD的专栏JD的专栏
运行总次数:0
代码可运行

前言:在接口设计上,对数据进行查询时,往往会采用分页查询的形式进行数据的拉取,主要是为了避免一次性返回过大的结果导致对网络,内存,客户端应用程序,集群服务等产生过大的压力,导致出现性能问题。在elasticsearch中分页查询主要有两种方式,from size分页查询与scroll深度分页查询。

一.from size分页查询

使用fromsize参数来进行分页查询。from参数用于指定查询结果的起始位置,size参数用于指定每页返回的文档数量。

操作样例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#Python
from elasticsearch import Elasticsearch
# 创建 Elasticsearch 客户端
es = Elasticsearch()
# 定义查询条件
query = {
    "query": {
        "match_all": {}  # 这里可以替换为其他查询条件
    },
    "size": 10,  # 每页返回的文档数量
    "from": 0  # 查询结果的起始位置
}
# 执行查询
result = es.search(index="your_index_name", body=query)
# 处理查询结果
total_hits = result["hits"]["total"]["value"]  # 总命中数
hits = result["hits"]["hits"]  # 查询命中的文档列表
for hit in hits:
    # 处理每个文档的数据
    doc_id = hit["_id"]
    source = hit["_source"]
# 输出分页信息
print(f"Total hits: {total_hits}")
print(f"Returned hits: {len(hits)}")

#Java
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
public class PaginationExample {
    public static void main(String[] args) {
        // 创建 Elasticsearch 客户端
        RestHighLevelClient client = new RestHighLevelClient();
        // 定义查询请求
        SearchRequest searchRequest = new SearchRequest("your_index_name");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchAllQuery()); // 这里可以替换为其他查询条件
        sourceBuilder.from(0); // 查询结果的起始位置
        sourceBuilder.size(10); // 每页返回的文档数量
        searchRequest.source(sourceBuilder);
        try {
            // 执行查询
            SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
            // 处理查询结果
            long totalHits = response.getHits().getTotalHits().value; // 总命中数
            SearchHit[] hits = response.getHits().getHits(); // 查询命中的文档列表
            for (SearchHit hit : hits) {
                // 处理每个文档的数据
                String docId = hit.getId();
                Map<String, Object> source = hit.getSourceAsMap();
                // ...
            }
            // 输出分页信息
            System.out.println("Total hits: " + totalHits);
            System.out.println("Returned hits: " + hits.length);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭 Elasticsearch 客户端
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

使用限制与分析

当我们在使用from size这种方式对elasticsearch返回的数据进行分页时,使用方式上类似于关系型数据库limit offset,offset

在日常搜索场景下,我们可以通过对结果进行评分的排序,来提高搜索结果的相关性,使用该方式将最相关的数据返回给客户端。设置from参数来指定查询结果的起始位置,size参数来指定每页返回的文档数量。

当我们使用这种方式进行分页查询时,elasticsearch默认上限为10000条数据。虽然我们可以通过设置该参数index.max_result_window来提高分页查询返回条数的上限,但提高该上限可能会造成以下问题,影响集群稳定运行。

  1. 内存消耗:较大的窗口大小意味着 Elasticsearch 需要为查询结果保留更多的内存空间。如果查询结果非常庞大,可能会导致 Elasticsearch 集群的内存消耗增加,从而影响性能和稳定性。
  2. 查询性能下降:当查询结果窗口较大时,Elasticsearch 需要处理更多的数据并返回更多的结果。这可能导致查询的响应时间增加,因为 Elasticsearch 需要更多的时间来处理和返回结果。
  3. 网络传输开销:如果查询结果窗口较大,将会返回更多的数据量。这可能会增加网络传输的开销,尤其是在分布式环境中跨节点传输结果时。
  4. 客户端资源消耗:较大的查询结果窗口可能会导致客户端应用程序需要处理更多的数据。如果客户端不具备足够的资源来处理大量的查询结果,可能会影响客户端的性能和稳定性。

当分页的数据超过10000条时,我们又需要返回大量的结果,我们可以通过search_after的方式。其操作步骤如下: 1. 首先我们获取一个pit,并设置有效时间为1分钟,其作用为创建一个时间点,保留索引当前的搜索状态,以避免多次搜索后,结果不一致。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
POST /my-index-000001/_pit?keep_alive=1m

然后elasticsearch会返回一个ID给我们。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "id": "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA=="
}

2. 在查询时,携带pit。此时我们在搜索时,搜索的结果均为该时间点的索引状态内的数据。搜索请求命中的数据会自动添加至携带了pit的搜索请求中。_shard_doc作为索引分片与文档在lucene内部的id的组合生成的唯一值,在我们的搜索请求中,我们可以自定义对齐排序。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GET /_search
{
  "size": 10000,
  "query": {
    "match" : {
      "user.id" : "elkbee"
    }
  },
  "pit": {
	    "id":  "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA==", 
	    "keep_alive": "1m"
  },
  "sort": [ 
    {"@timestamp": {"order": "asc", "format": "strict_date_optional_time_nanos", "numeric_type" : "date_nanos" }}
  ]
}

3. 当我们需要获取下一页结果时,只需要将上一次命中的排序值,作为参数,重新执行一次search_after请求即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GET /_search
{
  "size": 10000,
  "query": {
    "match" : {
      "user.id" : "elkbee"
    }
  },
  "pit": {
	    "id":  "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA==", 
	    "keep_alive": "1m"
  },
  "sort": [
    {"@timestamp": {"order": "asc", "format": "strict_date_optional_time_nanos"}}
  ],
  "search_after": [                                
    "2021-05-20T05:30:04.832Z",
    4294967298
  ],
  "track_total_hits": false                        
}

4. 在使用完成后,我们还需要将pit进行删除。以结束该时间点的索引状态。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
DELETE /_pit
{
    "id" : "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA=="
}

二.scroll深度分页查询

通过scroll游标在索引中对数据进行滚动请求,每次只需要携带_scroll_id,就在多个请求之间保持查询上下文,并逐步滚动结果集,以获取更多的文档。

操作步骤与样例

  1. 发起初始查询:您需要执行初始查询来获取第一页的结果集。在查询请求中,需要设置 scroll 参数来指定滚动请求的有效期,并设置 size 参数来指定每次滚动请求返回的文档数量。
  2. 处理初始查询结果:初始查询会返回一批文档结果。您可以遍历这些结果并处理每个文档的数据。
  3. 发起滚动请求:使用上一步返回的滚动 ID(scroll_id),您可以发起滚动请求来获取下一页的文档。在每个滚动请求中,需要设置相同的 scroll 参数和使用上一个请求返回的滚动 ID。
  4. 处理滚动请求结果:滚动请求会返回下一页的文档结果。您可以遍历这些结果并处理每个文档的数据。
  5. 重复步骤 3 和步骤 4:您可以重复发起滚动请求并处理结果,直到没有更多的文档返回为止。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#发起一个scroll查询,游标id的有效时间为一分钟。
POST /my-index-000001/_search?scroll=1m
{
  "size": 100,
  "query": {
    "match": {
      "message": "foo"
    }
  }
}

使用限制与分析

在scroll查询中,scroll_id的有效时间默认为1分钟,我们在进行大量数据查询,或进行大量数据导出时,为了方便可能会将有效时间设置的很大,如果keep alive时间设置过大可能会造成以下问题:

  1. 资源占用:大数据量级的Scroll 查询会占用集群资源,包括内存、CPU 和网络带宽。如果将有效时间设置得非常大,那么服务器需要保持滚动查询的上下文信息,并且需要为每个滚动查询保留足够的资源。这可能导致集群资源的过度消耗,降低整体性能和稳定性。
  2. 内存泄漏:如果滚动查询的有效时间过长,可能导致内存泄漏问题。因为elasticsearch需要在内存中维护滚动查询的上下文信息,如果这些信息无法及时释放,可能会导致内存占用不断增加,最终耗尽服务器的可用内存。
  3. 查询一致性:滚动查询的有效时间过长可能会导致查询结果的一致性问题。如果在滚动查询期间有新的文档被索引,而滚动查询的有效时间仍在进行中,那么这些新文档将不会包含在滚动查询的结果中。这可能会导致查询结果不准确或不完整。

因此,我们需要根据业务需求与集群资源负载,合理的设置keep alive的有效时间范围,将有效时间设置为适当的范围,以便集群能够一定时间内能够处理滚动查询,并及时释放资源。

在新版本的elasticsearch中,已经引入了Search_after API与Cursor API来逐步替代Scroll API,我们将在后续的文章中进行讨论。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
强化学习从基础到进阶–案例与实践[8]:近端策略优化(proximal policy optimization,PPO)算法
在介绍近端策略优化(proximal policy optimization,PPO) 之前,我们先回顾同策略和异策略这两种训练方法的区别。在强化学习里面,要学习的是一个智能体。如果要学习的智能体和与环境交互的智能体是相同的,我们称之为同策略。如果要学习的智能体和与环境交互的智能体不是相同的,我们称之为异策略。
汀丶人工智能
2023/10/11
1.2K0
强化学习从基础到进阶–案例与实践[8]:近端策略优化(proximal policy optimization,PPO)算法
强化学习从基础到进阶-常见问题和面试必知必答8:近端策略优化(proximal policy optimization,PPO)算法
经典策略梯度的大部分时间花在数据采样上,即当我们的智能体与环境交互后,我们就要进行策略模型的更新。但是对于一个回合我们仅能更新策略模型一次,更新完后我们就要花时间重新采样数据,然后才能再次进行如上的更新。
汀丶人工智能
2023/06/28
5070
强化学习系列(八)--PPO
回顾上文中的DDPG,DDPG是源于DQN,它使用神经网络替换maxQ(s',a')的功能来解决连续空间问题。也就是说DDPG的Actor网络输出的是一个动作,他的目标是输出一个动作,这个动作输入到Critic后,能过获得最大的Q值。和DQN一样,更新的时候如果更新目标在不断变化会使学习过程困难,所以需要固定目标网络,求target的网络更新后再赋值参数,所以需要四个网络。
languageX
2022/04/01
4.8K0
【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
MAPPO 是一种多智能体强化学习算法,基于单智能体的 PPO (Proximal Policy Optimization) 算法进行了扩展,专门设计用于解决多智能体协作和竞争环境中的决策问题。
不去幼儿园
2024/12/03
1.1K0
【MARL】深入理解多智能体近端策略优化(MAPPO)算法与调参
强化学习(十六) 深度确定性策略梯度(DDPG)
    在强化学习(十五) A3C中,我们讨论了使用多线程的方法来解决Actor-Critic难收敛的问题,今天我们不使用多线程,而是使用和DDQN类似的方法:即经验回放和双网络的方法来改进Actor-Critic难收敛的问题,这个算法就是是深度确定性策略梯度(Deep Deterministic Policy Gradient,以下简称DDPG)。
刘建平Pinard
2019/03/05
5.8K0
近端策略优化算法(PPO)
策略梯度迭代,通过计算策略梯度的估计,并利用随机梯度上升算法进行迭代。其常用的梯度估计形式为: E^t[∇θlogπθ(at∣st)A^t] \hat{\mathbb{E}}_t[\nabla_\theta log \pi_\theta(a_t | s_t)\hat{A}_t] E^t​[∇θ​logπθ​(at​∣st​)A^t​] 其中πθ\pi_\thetaπθ​为随机策略,A^t\hat{A}_tA^t​是优势函数在时间步t的估计,其损失函数为: LPG(θ)=E^t[logπθ(at∣st)A^t] L^{PG}(\theta)=\hat{\mathbb{E}}_t[log_{\pi_\theta}(a_t|s_t)\hat{A}_t] LPG(θ)=E^t​[logπθ​​(at​∣st​)A^t​]
Steve Wang
2020/02/18
1.5K0
近端策略优化算法(PPO)
DeepSeek 背后的数学原理:深入探究群体相对策略优化 (GRPO)
群体相对策略优化 (GRPO,Group Relative Policy Optimization) 是一种强化学习 (RL) 算法,专门用于增强大型语言模型 (LLM) 中的推理能力。与严重依赖外部评估模型(价值函数)指导学习的传统 RL 方法不同,GRPO 通过评估彼此相关的响应组来优化模型。这种方法可以提高训练效率,使 GRPO 成为需要复杂问题解决和长链思维的推理任务的理想选择。
致Great
2025/02/12
2.4K0
DeepSeek 背后的数学原理:深入探究群体相对策略优化 (GRPO)
深度强化学习落地方法论算法选择:DQN、DDPG、A3C、PPO、TD3
虽然每年 RL 方向的 paper 满天飞,但真正具有普遍实用价值的突破性工作实在不多,大多数还是在经典框架基础上的改进和扩展。DRL 常规武器库里的存货主要还是老三样:DQN,DDPG 和 A3C,它们是深度学习时代最成熟、最能体现智慧结晶的三个 DRL 框架,你可以在 GitHub 上找到无数相关代码,有 OpenAI,DeepMind 和 Nvidia 这些大公司的,也有个人爱好者的。对于 DRL 初学者,它们是最佳的敲门砖;对于算法研究者,它们是最厚实的 “巨人肩膀”;对于算法工程师,它们是最顺手的试金石。你完全可以把三个框架都放到项目模拟器上跑一跑,看哪个效果好就用哪个。当然,这三个算法框架都有各自的特点和适用 domain,结合对项目的分析,是可以提前评估最合适的算法的。
汀丶人工智能
2023/10/11
6.4K0
深度强化学习落地方法论算法选择:DQN、DDPG、A3C、PPO、TD3
强化学习算法解析:PPO(Proximal Policy Optimization)
PPO(近端策略优化)是OpenAI于2017年提出的一种策略梯度类算法,以其高效性、稳定性和易实现性成为强化学习领域的主流算法。以下从核心原理、数学推导、代码实现到应用场景进行系统解析。
jack.yang
2025/04/05
3.1K0
强化学习算法解析:PPO(Proximal Policy Optimization)
【强化学习】近端策略优化算法(PPO)万字详解(附代码)
近端策略优化、PPO(Proximal Policy Optimization)是一种强化学习算法,设计的目的是在复杂任务中既保证性能提升,又让算法更稳定和高效。以下用通俗易懂的方式介绍其核心概念和流程。
不去幼儿园
2025/01/02
13.2K0
【强化学习】近端策略优化算法(PPO)万字详解(附代码)
强化学习方法小结
在介绍强化学习算法之前先介绍一个比较重要的概念,就是Bellman方程,该方程表示动作价值函数,即在某一个状态下,计算出每种动作所对应的value(或者说预期的reward)。
marsggbo
2019/12/23
7340
强化学习方法小结
强化学习基础篇3:DQN、Actor-Critic详细讲解
在之前的内容中,我们讲解了Q-learning和Sarsa算法。在这两个算法中,需要用一个Q表格来记录不同状态动作对应的价值,即一个大小为 $状态个数,动作个数$ 的二维数组。在一些简单的强化学习环境中,比如迷宫游戏中(图1a),迷宫大小为4*4,因此该游戏存在16个state;而悬崖问题(图1b)的地图大小为 4*12,因此在该问题中状态数量为48,这些都属于数量较少的状态,所以可以用Q表格来记录对应的状态动作价值。但当我们需要应用强化学习来解决实际问题时,比如解决国际象棋问题或围棋问题,那么环境中就会包含 $10^{47}$ 个state或 $10^{170}$ 个state,如此庞大的状态数量已经很难用Q表格来进行存储,更不要说在3D仿真环境中,机器人手脚弯曲的状态是完全不可数的。由此可以看到Q表格在大状态问题和不可数状态问题时的局限性。同时,在一个强化学习环境中,不是所有的状态都会被经常访问,其中有些状态的访问次数很少或几乎为零,这就会导致价值估计并不可靠。
汀丶人工智能
2023/06/03
2.6K0
强化学习基础篇3:DQN、Actor-Critic详细讲解
强化学习笔记6:值函数估计Value function Approximation
\(\delta\) scalar number \(E_t\) 维度和s维度一致
列夫托尔斯昊
2020/08/25
7450
Hands on Reinforcement Learning 09 Policy Gradient Algorithm
本书之前介绍的 Q-learning、DQN 及 DQN 改进算法都是基于价值(value-based)的方法,其中 Q-learning 是处理有限状态的算法,而 DQN 可以用来解决连续状态的问题。在强化学习中,除了基于值函数的方法,还有一支非常经典的方法,那就是基于策略(policy-based)的方法。对比两者,基于值函数的方法主要是学习值函数,然后根据值函数导出一个策略,学习过程中并不存在一个显式的策略;而基于策略的方法则是直接显式地学习一个目标策略。策略梯度是基于策略的方法的基础,本章从策略梯度算法说起。
一只野生彩色铅笔
2023/04/09
4610
Hands on Reinforcement Learning 09 Policy Gradient Algorithm
强化学习(十三) 策略梯度(Policy Gradient)
    在前面讲到的DQN系列强化学习算法中,我们主要对价值函数进行了近似表示,基于价值来学习。这种Value Based强化学习方法在很多领域都得到比较好的应用,但是Value Based强化学习方法也有很多局限性,因此在另一些场景下我们需要其他的方法,比如本篇讨论的策略梯度(Policy Gradient),它是Policy Based强化学习方法,基于策略来学习。
刘建平Pinard
2018/12/27
1.5K0
强化学习算法TD3论文的翻译与解读:延迟学习、软更新、策略噪声、梯度截取
强化学习算法 TD3 论文:Addressing Function Approximation Error in Actor-Critic Methods 2018.10. ,作者本人的 TD3 代码,PyTroch 实现
汀丶人工智能
2023/10/11
2.4K0
强化学习算法TD3论文的翻译与解读:延迟学习、软更新、策略噪声、梯度截取
强化学习-5:Model-free control
贪婪策略梯度法如果用V(s),需要MDP已知 用Q(s,a),不需要已知MDP
列夫托尔斯昊
2020/08/25
7180
强化学习-5:Model-free control
【万字专栏总结】离线强化学习(OfflineRL)总结(原理、数据集、算法、复杂性分析、超参数调优等)
强化学习发展的特别早,但一直不温不火,其中Sutton老爷子早在1998年就写了强化学习领域的圣经书籍:An Introduction : Reinforcement Learning ,但也并未开启强化学习发展的新局面。直到2012年,深度学习广泛兴起,大规模的神经网络被成功用于解决自然语言处理,计算机视觉等领域,人工智能的各个方向才开始快速发展,强化学习领域最典型的就是2013年DeepMind公司的Volodymyr Mnih发表Playing Atari with Deep Reinforcement Learning(DQN技术),可以说开启了深度强化学习技术发展的新高潮,2015年该论文的加强版Human-level control through deep reinforcement learning 登上Nature, 以及2016年Nature上的AlphaGo: Mastering the game of Go with deep neural networks and tree search 充分证明了深度强化学习技术的发展潜力。
深度强化学习实验室
2022/09/23
11.3K0
【万字专栏总结】离线强化学习(OfflineRL)总结(原理、数据集、算法、复杂性分析、超参数调优等)
Hands on Reinforcement Learning 11 Trust Region Policy Optimization
本书之前介绍的基于策略的方法包括策略梯度算法和 Actor-Critic 算法。这些方法虽然简单、直观,但在实际应用过程中会遇到训练不稳定的情况。回顾一下基于策略的方法:参数化智能体的策略,并设计衡量策略好坏的目标函数,通过梯度上升的方法来最大化这个目标函数,使得策略最优。具体来说,假设
一只野生彩色铅笔
2023/04/09
4260
《深度强化学习》面试题汇总
4. 强化学习的损失函数(loss function)是什么?和深度学习的损失函数有何关系?
深度强化学习实验室
2019/11/21
5.1K0
《深度强化学习》面试题汇总
推荐阅读
相关推荐
强化学习从基础到进阶–案例与实践[8]:近端策略优化(proximal policy optimization,PPO)算法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验