热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Elasticsearch分页查询策略详解

本文详细介绍了Elasticsearch中的分页查询机制,包括基本的分页查询流程、'from-size'浅分页与'scroll'深分页的区别及应用场景,以及两者在性能上的对比。

Elasticsearch 分页查询概述


在Elasticsearch中,分页查询是一种常见的需求,特别是在处理大量数据时。通常,分页查询的过程如下:



  1. 客户端向集群中的任意节点发送请求。

  2. 该节点将请求转发至各个分片,每个分片返回指定数量的结果。

  3. 节点收集所有分片返回的数据,合并并排序,最后返回给客户端。


当需要获取特定范围的数据时,例如第10条到第20条记录,就需要使用分页查询功能。



'from-size' 浅分页


'from-size'分页是一种简单的分页方式,通过设置'from'参数来指定起始位置,'size'参数来指定返回的记录数。例如,查询前10条记录的请求如下:


{
"from": 0,
"size": 10,
"query": {
"term": {
"user": "kimchy"
}
}
}

这种方式虽然简单,但随着分页深度的增加,性能会显著下降。测试表明,随着'from'值的增大,查询时间也会相应增加,尤其是在数据量较大的情况下。



'scroll' 深分页


'scroll'分页主要用于一次性检索大量数据,类似于数据库中的游标。它通过维护一个快照来记录当前读取的位置,确保后续查询能够快速继续。使用'scroll'时,首先发起一个搜索请求,并获取一个'_scroll_id',之后使用这个ID继续检索:


curl -XGET 'localhost:9200/twitter/tweet/_search?scroll=1m' -d '{"query": {"match": {"title": "elasticsearch"}}}'

然后使用返回的'_scroll_id'继续检索:


curl -XGET 'localhost:9200/_search/scroll?scroll=1m&scroll_id=c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1'

'_scroll_id'是一个经过Base64编码的字符串,包含了查询的相关信息。'scroll'分页在处理大数据集时表现出色,因为它避免了重复查询和数据剔除的过程。



性能测试


为了比较'from-size'和'scroll'分页的性能,我们进行了如下测试。首先,使用Java客户端初始化Elasticsearch连接:



org.elasticsearch
elasticsearch
5.5.1


private static TransportClient client;
private static String INDEX = "index_name";
private static String TYPE = "type_name";

public static TransportClient init() {
Settings settings = Settings.builder()
.put("client.transport.sniff", true)
.put("cluster.name", "cluster_name")
.build();
client = new PreBuiltTransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
return client;
}

public static void main(String[] args) {
TransportClient client = init();
// 使用client执行查询
}

以下是'from-size'分页的测试代码:


System.out.println("from-size模式启动!");
Date begin = new Date();
long count = client.prepareCount(INDEX).setTypes(TYPE).execute().actionGet().getCount();
SearchRequestBuilder requestBuilder = client.prepareSearch(INDEX).setTypes(TYPE).setQuery(QueryBuilders.matchAllQuery());

for (int i = 0, sum = 0; sum SearchResponse respOnse= requestBuilder.setFrom(i * 50000).setSize(50000).execute().actionGet();
sum += response.getHits().hits().length;
System.out.println("总量" + count + " 已经查到" + sum);
}

Date end = new Date();
System.out.println("耗时: " + (end.getTime() - begin.getTime()));

以下是'scroll'分页的测试代码:


System.out.println("scroll模式启动!");
begin = new Date();
SearchResponse scrollRespOnse= client.prepareSearch(INDEX)
.setSearchType(SearchType.SCAN)
.setSize(10000)
.setScroll(TimeValue.timeValueMinutes(1))
.execute().actionGet();
count = scrollResponse.getHits().getTotalHits();

for (int i = 0, sum = 0; sum scrollRespOnse= client.prepareSearchScroll(scrollResponse.getScrollId())
.setScroll(TimeValue.timeValueMinutes(8))
.execute().actionGet();
sum += scrollResponse.getHits().hits().length;
System.out.println("总量" + count + " 已经查到" + sum);
}

end = new Date();
System.out.println("耗时: " + (end.getTime() - begin.getTime()));

测试结果显示,在33万多条数据的情况下,'scroll'分页的性能远优于'from-size'分页。对于大数据量的操作,建议使用'scroll'分页以提高查询效率。


推荐阅读
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • 管理UINavigationController中的手势返回 - Managing Swipe Back Gestures in UINavigationController
    本文介绍了如何在一个简单的闪存卡片应用中实现平滑的手势返回功能,以增强用户体验。 ... [详细]
  • 本文详细介绍了`android.os.Binder.getCallingPid()`方法的功能和应用场景,并提供了多个实际的代码示例。通过这些示例,开发者可以更好地理解如何在不同的开发场景中使用该方法。 ... [详细]
  • SDWebImage第三方库学习
    1、基本使用方法异步下载并缓存-(void)sd_setImageWithURL:(nullableNSURL*)urlNS_REFINED_FOR_SWIFT;使用占位图片& ... [详细]
  • 我自己做了一个网站图片的抓取,感觉速度有点慢抓取4000张图片可能得用15分钟左右的时间,我百度看用线程可以加快抓取,然后创建了5个线程抓取,但是5个线程是同步执行同样的操作一个图片就 ... [详细]
  • PostgreSQL 12 版本预览:分离 max_wal_senders 和 max_connections 的连接槽处理
    本文介绍了 PostgreSQL 12 中的一项重要改进,即 max_wal_senders 参数不再计入 max_connections,从而解决了流复制连接槽不足的问题。 ... [详细]
  • 可参照github代码:https:github.comrabbitmqrabbitmq-tutorialsblobmasterjavaEmitLogTopic.ja ... [详细]
  • 短视频app源码,Android开发底部滑出菜单首先依赖三方库implementationandroidx.appcompat:appcompat:1.2.0im ... [详细]
  • PBO(PixelBufferObject),将像素数据存储在显存中。优点:1、快速的像素数据传递,它采用了一种叫DMA(DirectM ... [详细]
  • 使用Tkinter构建51Ape无损音乐爬虫UI
    本文介绍了如何使用Python的内置模块Tkinter来构建一个简单的用户界面,用于爬取51Ape网站上的无损音乐百度云链接。虽然Tkinter入门相对简单,但在实际开发过程中由于文档不足可能会带来一些不便。 ... [详细]
  • WCF类型共享的最佳实践
    在使用WCF服务时,经常会遇到同一个实体类型在不同服务中被生成为不同版本的问题。本文将介绍几种有效的类型共享方法,以解决这一常见问题。 ... [详细]
  • 原文地址:https:blog.csdn.netqq_35361471articledetails84715491原文地址:https:blog.cs ... [详细]
  • 本文将深入探讨 Unreal Engine 4 (UE4) 中的距离场技术,包括其原理、实现细节以及在渲染中的应用。距离场技术在现代游戏引擎中用于提高光照和阴影的效果,尤其是在处理复杂几何形状时。文章将结合具体代码示例,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 在iOS开发中,多线程技术的应用非常广泛,能够高效地执行多个调度任务。本文将重点介绍GCD(Grand Central Dispatch)在多线程开发中的应用,包括其函数和队列的实现细节。 ... [详细]
  • 在Android开发中,当TextView的高度固定且内容超出时,可以通过设置其内置的滚动条属性来实现垂直滚动功能。具体来说,可以通过配置`android:scrollbars="vertical"`来启用垂直滚动,确保用户能够查看完整的内容。此外,为了优化用户体验,建议结合`setMovementMethod(ScrollerMovementMethod.getInstance())`方法,使滚动操作更加流畅和自然。 ... [详细]
author-avatar
碳酸钙baby_849
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有