之前一直使用from size进行分页查询(深度分页),当数据量大的时候,对全部数据进行遍历,使用from size性能会很差,然后了解了下scroll方法,简单讲解一下scroll方法的使用。
从网上了解到,scroll类似于数据库中的游标,不考虑排序的时候,可以结合SearchType.SCAN使用。
1.首先,创建一个school索引,分片数量为5
2.使用以下方法,来创造一些简单的假数据
/**
* 创造假数据
* @param count 数据量
*/
public static void insertData(int count) {
System.out.println("-----------begin------------");
Student student=new Student();
for (int i=1;i<=count;i++){
student.setName("name"+i);
student.setId(i);
String id="id_"+i;//设置存入ES中的ID
//插入数据(数据量大时,最好使用批量插入,此处为单条插入)
esUtils.insert("school","student",id,new Gson().toJson(student));
}
System.out.println("-----------end------------");
}
Sudent类
package com.es.scroll.bean;
public class Student {
private String name;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
ElasticsearchUtils
package com.es.scroll.esutil;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
public class ElasticsearchUtils {
private Client client;
public ElasticsearchUtils(String clusterName, String ipAddress,int port) {
Settings settings = ImmutableSettings
.settingsBuilder()
//设置集群名称
.put("cluster.name", clusterName)
.put("client.transport.ignore_cluster_name", false)
.put("node.client", true).put("client.transport.sniff", true)
.build();
client = new TransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress(ipAddress,
port));
}
public Client getClient(){
return this.client;
}
/**
* 创建索引
* @param indexName 索引名称,相当于数据库名称
* @param typeName 索引类型,相当于数据库中的表名
* @param id id名称,相当于每个表中某一行记录的标识
* @param jsonData json数据
*/
public void insert(String indexName, String typeName, String id,
String jsonData) {
IndexRequestBuilder requestBuilder = client.prepareIndex(indexName,
typeName, id).setRefresh(true);//设置索引名称,索引类型,id
requestBuilder.setSource(jsonData).execute().actionGet();//创建索引
}
}
数据如下:
3.使用scroll结合scan遍历所有数据
package com.es.scroll;
import com.es.scroll.bean.Student;
import com.es.scroll.esutil.ElasticsearchUtils;
import com.google.gson.Gson;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
public class MainApplication {
private static int i=0;
private static ElasticsearchUtils esUtils;
public static void main(String[] args) {
//创建ElasticsearchUtils对象,设置集群名称,IP地址,端口号
esUtils = new ElasticsearchUtils("im_shanmenglu", "localhost", 9300);
// insertData(10000);
//获取Client对象,设置索引名称,搜索类型(SearchType.SCAN),搜索数量,发送请求
SearchResponse searchResponse = esUtils.getClient()
.prepareSearch("school").setSearchType(SearchType.SCAN)
.setSize(10).setScroll(new TimeValue(20000)).execute()
.actionGet();//注意:首次搜索并不包含数据
//获取总数量
long totalCount = searchResponse.getHits().getTotalHits();
int page=(int)totalCount/(5*10);//计算总页数,每次搜索数量为分片数*设置的size大小
System.out.println(totalCount);
for (int i = 0; i <= page; i++) {
//再次发送请求,并使用上次搜索结果的ScrollId
searchResponse = esUtils.getClient()
.prepareSearchScroll(searchResponse.getScrollId())
.setScroll(new TimeValue(20000)).execute()
.actionGet();
parseSearchResponse(searchResponse);
}
}
public static void parseSearchResponse(SearchResponse searchResponse) {
SearchHits hits = searchResponse.getHits();
System.out.println("-----------begin------------");
for (SearchHit searchHit : hits.getHits()) {
try {
i++;
String id = searchHit.getId();
System.out.println("第" + i + "条数据:" + id);
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("-----------end------------");
}
/**
* 创造假数据
* @param count 数据量
*/
public static void insertData(int count) {
System.out.println("-----------begin------------");
Student student=new Student();
for (int i=1;i<=count;i++){
student.setName("name"+i);
student.setId(i);
String id="id_"+i;//设置存入ES中的ID
//插入数据(数据量大时,最好使用批量插入,此处为单条插入)
esUtils.insert("school","student",id,new Gson().toJson(student));
}
System.out.println("-----------end------------");
}
}
/**部分数据
* 10000
-----------begin------------
第1条数据:id_11
第2条数据:id_16
第3条数据:id_23
第4条数据:id_28
第5条数据:id_30
第6条数据:id_35
第7条数据:id_42
第8条数据:id_47
第9条数据:id_2
第10条数据:id_7
第11条数据:id_12
第12条数据:id_17
第13条数据:id_24
第14条数据:id_29
第15条数据:id_31
第16条数据:id_36
第17条数据:id_43
第18条数据:id_48
第19条数据:id_3
第20条数据:id_8
第21条数据:id_13
第22条数据:id_18
第23条数据:id_20
第24条数据:id_25
第25条数据:id_32
第26条数据:id_37
第27条数据:id_44
第28条数据:id_49
第29条数据:id_4
第30条数据:id_9
第31条数据:id_14
第32条数据:id_19
第33条数据:id_21
第34条数据:id_26
第35条数据:id_33
第36条数据:id_38
第37条数据:id_40
第38条数据:id_45
第39条数据:id_52
第40条数据:id_5
第41条数据:id_10
第42条数据:id_15
第43条数据:id_22
第44条数据:id_27
第45条数据:id_34
第46条数据:id_39
第47条数据:id_41
第48条数据:id_46
第49条数据:id_1
第50条数据:id_6
-----------end------------
-----------begin------------
第51条数据:id_54
第52条数据:id_59
第53条数据:id_61
第54条数据:id_66
第55条数据:id_73
第56条数据:id_78
第57条数据:id_80
第58条数据:id_85
第59条数据:id_92
第60条数据:id_102
第61条数据:id_50
第62条数据:id_55
第63条数据:id_62
第64条数据:id_67
第65条数据:id_74
第66条数据:id_79
第67条数据:id_81
第68条数据:id_86
第69条数据:id_93
第70条数据:id_103
第71条数据:id_51
第72条数据:id_56
第73条数据:id_63
第74条数据:id_68
第75条数据:id_70
第76条数据:id_75
第77条数据:id_82
第78条数据:id_87
第79条数据:id_94
第80条数据:id_104
第81条数据:id_57
第82条数据:id_64
第83条数据:id_69
第84条数据:id_71
第85条数据:id_76
第86条数据:id_83
第87条数据:id_88
第88条数据:id_90
第89条数据:id_95
第90条数据:id_100
第91条数据:id_53
第92条数据:id_58
第93条数据:id_60
第94条数据:id_65
第95条数据:id_72
第96条数据:id_77
第97条数据:id_84
第98条数据:id_89
第99条数据:id_91
第100条数据:id_101
-----------end------------
-----------begin------------
第101条数据:id_107
第102条数据:id_114
第103条数据:id_119
第104条数据:id_121
第105条数据:id_126
第106条数据:id_133
第107条数据:id_138
第108条数据:id_97
第109条数据:id_171
第110条数据:id_176
第111条数据:id_108
第112条数据:id_110
第113条数据:id_115
第114条数据:id_122
第115条数据:id_127
第116条数据:id_134
第117条数据:id_139
第118条数据:id_98
第119条数据:id_172
第120条数据:id_177
第121条数据:id_109
第122条数据:id_111
第123条数据:id_116
第124条数据:id_123
第125条数据:id_128
第126条数据:id_130
第127条数据:id_135
第128条数据:id_99
第129条数据:id_166
第130条数据:id_173
第131条数据:id_105
第132条数据:id_112
第133条数据:id_117
第134条数据:id_124
第135条数据:id_129
第136条数据:id_131
第137条数据:id_136
第138条数据:id_143
第139条数据:id_179
第140条数据:id_181
第141条数据:id_106
第142条数据:id_113
第143条数据:id_118
第144条数据:id_120
第145条数据:id_125
第146条数据:id_132
第147条数据:id_137
第148条数据:id_96
第149条数据:id_168
第150条数据:id_170
-----------end------------
-----------begin------------
第151条数据:id_183
第152条数据:id_140
第153条数据:id_145
第154条数据:id_152
第155条数据:id_157
第156条数据:id_164
第157条数据:id_169
第158条数据:id_188
第159条数据:id_190
第160条数据:id_195
第161条数据:id_184
第162条数据:id_141
第163条数据:id_146
第164条数据:id_153
第165条数据:id_158
第166条数据:id_160
第167条数据:id_165
第168条数据:id_189
第169条数据:id_191
第170条数据:id_196
第171条数据:id_178
第172条数据:id_180
第173条数据:id_142
第174条数据:id_147
第175条数据:id_154
第176条数据:id_159
第177条数据:id_161
第178条数据:id_185
第179条数据:id_192
第180条数据:id_197
第181条数据:id_186
第182条数据:id_148
第183条数据:id_150
第184条数据:id_155
第185条数据:id_162
第186条数据:id_167
第187条数据:id_174
第188条数据:id_193
第189条数据:id_198
第190条数据:id_201
第191条数据:id_175
第192条数据:id_182
第193条数据:id_144
第194条数据:id_149
第195条数据:id_151
第196条数据:id_156
第197条数据:id_163
第198条数据:id_187
第199条数据:id_194
第200条数据:id_199
-----------end------------
*/
此处截取了部分输出数据,可以看出使用scroll进行分页查询,每次查询的数据量为分片的数量*首次查询设置的size大小,TimeValue表示需要保持搜索的上下文时间。