Elasticsearch Sliced Scroll分页检索案例分享

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: Elasticsearch Sliced Scroll分页检索案例分享 我们在文章《Elasticsearch Scroll分页检索案例分享》中介绍了elasticsearch scroll的基本用法,本文介绍Elasticsearch Sliced Scroll分页检索功能。
Elasticsearch Sliced Scroll分页检索案例分享

我们在文章《 Elasticsearch Scroll分页检索案例分享》中介绍了elasticsearch scroll的基本用法,本文介绍Elasticsearch Sliced Scroll分页检索功能。

1.准备工作
参考文档《 高性能elasticsearch ORM开发库使用介绍》导入和配置es客户端

2.定义Sliced Scroll检索dsl
创建配置文件-在resources目录下定义文件scroll.xml
esmapper/scroll.xml
文件内容包含Sliced Scroll检索dsl语句-scrollSliceQuery
<property name="scrollSliceQuery">
        <![CDATA[
         {
           "slice": {
                "id": $id,
                "max": $max
            },
            "size":$size,
            "query": {
                "term" : {
                    "gc.jvmGcOldCount" : 3
                }
            }
        }
        ]]>
    </property>

3.串行方式执行slice检索
/**
 * 串行方式执行slice scroll操作
 */
@Test
public void testSliceScroll() {
	ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/scroll.xml");
	List<String> scrollIds = new ArrayList<>();
	long starttime = System.currentTimeMillis();
	//scroll slice分页检索
	int max = 6;
	long realTotalSize = 0;
	for (int i = 0; i < max; i++) {
		Map params = new HashMap();
		params.put("id", i);
		params.put("max", max);//最多6个slice,不能大于share数
		params.put("size", 100);//每页100条记录
		ESDatas<Map> sliceResponse = clientUtil.searchList("agentstat-*/_search?scroll=1m",
				"scrollSliceQuery", params,Map.class);
		List<Map> sliceDatas = sliceResponse.getDatas();
		realTotalSize = realTotalSize + sliceDatas.size();
		long totalSize = sliceResponse.getTotalSize();
		String scrollId = sliceResponse.getScrollId();
		if (scrollId != null)
			scrollIds.add(scrollId);
		System.out.println("totalSize:" + totalSize);
		System.out.println("scrollId:" + scrollId);
		if (sliceDatas != null && sliceDatas.size() >= 100) {//每页100条记录,迭代scrollid,遍历scroll分页结果
			do {
				sliceResponse = clientUtil.searchScroll("1m", scrollId, Map.class);
				String sliceScrollId = sliceResponse.getScrollId();
				if (sliceScrollId != null)
					scrollIds.add(sliceScrollId);
				sliceDatas = sliceResponse.getDatas();
				if (sliceDatas == null || sliceDatas.size() < 100) {
					break;
				}
				realTotalSize = realTotalSize + sliceDatas.size();
			} while (true);
		}
	}
      //打印处理耗时和实际检索到的数据
	long endtime = System.currentTimeMillis();
	System.out.println("耗时:"+(endtime - starttime)+",realTotalSize:"+realTotalSize);
	//查询存在es服务器上的scroll上下文信息
	String scrolls = clientUtil.executeHttp("_nodes/stats/indices/search", ClientUtil.HTTP_GET);
	System.out.println(scrolls);
	//处理完毕后清除scroll上下文信息
	if(scrollIds.size() > 0) {
		scrolls = clientUtil.deleteScrolls(scrollIds);
		System.out.println(scrolls);
	}
	//清理完毕后查看scroll上下文信息
	scrolls = clientUtil.executeHttp("_nodes/stats/indices/search", ClientUtil.HTTP_GET);
	System.out.println(scrolls);
}

4.并行方式执行slice检索
//用来存放实际slice检索总记录数
long realTotalSize ;
//辅助方法,用来累计每次scroll获取到的记录数
synchronized void incrementSize(int size){
	this.realTotalSize = this.realTotalSize + size;
}
/**
 * 并行方式执行slice scroll操作
 */
@Test
public void testParralSliceScroll() {
	final ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil("esmapper/scroll.xml");
	final List<String> scrollIds = new ArrayList<>();
	long starttime = System.currentTimeMillis();
	//scroll slice分页检索
	final int max = 6;
	final CountDownLatch countDownLatch = new CountDownLatch(max);//线程任务完成计数器,每个线程对应一个sclice,每运行完一个slice任务,countDownLatch计数减去1

	for (int j = 0; j < max; j++) {//启动max个线程,并行处理每个slice任务
		final int i = j;
		Thread sliceThread = new Thread(new Runnable() {//多线程并行执行scroll操作做,每个线程对应一个sclice

			@Override
			public void run() {
				Map params = new HashMap();
				params.put("id", i);
				params.put("max", max);//最多6个slice,不能大于share数
				params.put("size", 100);//每页100条记录
				ESDatas<Map> sliceResponse = clientUtil.searchList("agentstat-*/_search?scroll=1m",
						"scrollSliceQuery", params,Map.class);
				List<Map> sliceDatas = sliceResponse.getDatas();
				incrementSize( sliceDatas.size());//统计实际处理的文档数量
				long totalSize = sliceResponse.getTotalSize();
				String scrollId = sliceResponse.getScrollId();
				if (scrollId != null)
					scrollIds.add(scrollId);
				System.out.println("totalSize:" + totalSize);
				System.out.println("scrollId:" + scrollId);
				if (sliceDatas != null && sliceDatas.size() >= 100) {//每页100条记录,迭代scrollid,遍历scroll分页结果
					do {
						sliceResponse = clientUtil.searchScroll("1m", scrollId, Map.class);
						String sliceScrollId = sliceResponse.getScrollId();
						if (sliceScrollId != null)
							scrollIds.add(sliceScrollId);
						sliceDatas = sliceResponse.getDatas();
						if (sliceDatas == null || sliceDatas.size() < 100) {
							break;
						}
						incrementSize( sliceDatas.size());//统计实际处理的文档数量
					} while (true);
				}
				countDownLatch.countDown();//slice检索完毕后计数器减1
			}

		});
		sliceThread.start();//启动线程
	}
	try {
		countDownLatch.await();//等待所有的线程执行完毕,计数器变成0
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
      //打印处理耗时和实际检索到的数据
	long endtime = System.currentTimeMillis();
	System.out.println("耗时:"+(endtime - starttime)+",realTotalSize:"+realTotalSize);
	//查询存在es服务器上的scroll上下文信息
	String scrolls = clientUtil.executeHttp("_nodes/stats/indices/search", ClientUtil.HTTP_GET);
//		System.out.println(scrolls);
	//处理完毕后清除scroll上下文信息
	if(scrollIds.size() > 0) {
		scrolls = clientUtil.deleteScrolls(scrollIds);
//			System.out.println(scrolls);
	}
	//清理完毕后查看scroll上下文信息
	scrolls = clientUtil.executeHttp("_nodes/stats/indices/search", ClientUtil.HTTP_GET);
//		System.out.println(scrolls);
}

通过串行运行和并行运行结果比较,并行处理的性能要好很多,实际检索到的文档数量等价一致。

5.参考文档
https://www.elastic.co/guide/en/elasticsearch/reference/6.2/search-request-scroll.html

6.开发交流
elasticsearch技术交流群:166471282

elasticsearch微信公众号:
img_a21db47cf20ac4820026d60bcb2b9470.jpe
相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
2月前
|
Docker 索引 容器
Elasticsearch跨集群检索配置
Elasticsearch跨集群检索配置
45 1
|
6月前
|
缓存 搜索推荐 关系型数据库
Elasticsearch - 闲聊ElasticSearch中的分页
Elasticsearch - 闲聊ElasticSearch中的分页
59 0
|
6月前
|
存储 关系型数据库 数据库
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
ElasticSearch深度解析入门篇:高效搜索解决方案的介绍与实战案例讲解,带你避坑
|
4月前
elasticsearch使用 scroll 滚动分页实战实例
elasticsearch使用 scroll 滚动分页实战实例
129 0
|
2月前
|
存储 JSON 测试技术
异步检索在 Elasticsearch 中的理论与实践
异步检索在 Elasticsearch 中的理论与实践
36 0
|
2月前
|
存储 JSON 关系型数据库
枯燥无味的Elasticsearch检索参数字典
枯燥无味的Elasticsearch检索参数字典
24 0
|
2月前
|
JSON 前端开发 Java
【Elasticsearch】黑马旅游案例
【Elasticsearch】黑马旅游案例
177 0
|
6月前
|
存储 Java 数据库
大厂案例 - 腾讯万亿级 Elasticsearch 架构实践2
大厂案例 - 腾讯万亿级 Elasticsearch 架构实践2
35 0
|
14天前
|
数据可视化 索引
elasticsearch head、kibana 安装和使用
elasticsearch head、kibana 安装和使用
|
26天前
|
存储 负载均衡 索引
linux7安装elasticsearch-7.4.0集群配置
linux7安装elasticsearch-7.4.0集群配置
112 0