elasticsearch的scroll查询

    前两天因为es索引和DB数据数量对应不上了,需要写一个任务,校验两边的数据进行多删少补。就是将多余的索引删除,缺少的索引进行添加。

    然后觉得也没啥,也没开多线程,直接一个线程循环查,跑任务就ok。第一次遇到问题是通过from/size方式查询es是有默认最大条数限制的,是10000;然后本人通过{- index.max_result_window:最大限制条数}直接改了限制的条数,其实这也已经足够了。可是因为索引数量是几千万条,到后面我发现性能会有下降,然后就引出了本次所说的scroll查询。

    大家都知道from/size会查询你所需要的数据前面所有数据然后剔除调无用的数据,然后我这有六个分片,可以想象一下后面性能会怎么样。然后看了一下scroll-scan查询的资料,发现并不需要读取大量数据再剔除不需要的,而是记录一下游标的位置,今儿快速的进行下次的读取。好了,话不多说,直接上代码

public Map<String,Object> findGoodsIdsByScroll(Integer pageNo, Integer pageSize,String scrollId) {
		Map<String,Object> result=Maps.newHashMap();
		String index = BASE_INDEX_NEW;
		String type = GOODS_TYPE;
		NativeSearchQueryBuilder nsb = new NativeSearchQueryBuilder();
	
		if (pageNo != null && pageSize != null) {
			if (pageNo < 0) {
				pageNo = 0;
			}
			Pageable pageable = new PageRequest(pageNo, pageSize);
			nsb.withPageable(pageable);
		}
		nsb.withIndices(index);// 索引 (库)
		nsb.withTypes(type);// 索引下的类型 (表)
		nsb.withFields("_id");// 查询字段
		
		SearchQuery searchQuery = nsb.build();
		long scollTimeInMillis = 2*60*1000; // scrollId过期时间
		if(StringUtils.isEmpty(scrollId)){
			scrollId = template.scan(searchQuery, scollTimeInMillis, false);			
		}
		SearchResponse response =template.getClient().prepareSearchScroll(scrollId).setScroll(TimeValue.timeValueMillis(scollTimeInMillis)).execute().actionGet();
		scrollId=response.getScrollId();
		result.put("scrollId", scrollId);
		List<String> ids=new ArrayList<String>(200);
		for (SearchHit hit : response.getHits()) {
			try{	
				String id=hit.getId();
				ids.add(id);
			}catch(Exception e){
				e.printStackTrace();
				System.out.println(response);
			}
		}
		result.put("ids", ids);
		if(CollectionUtils.isEmpty(ids)){
			template.clearScroll(scrollId); //无查询结果清除
		}
		return result;
	}
    大概说下,先通过scan查询获取一个base64的长字符串,即scrollId,然后通过scrollId去查询索引数据即可。然后运行发现性能有着明显的提升。

猜你喜欢

转载自blog.csdn.net/weixin_39605083/article/details/80985352