jest github 地址:https://github.com/searchbox-io/Jest
引入 jar 包:
io.searchbox
jest
5.3.3
初始化
JestClient client;
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(new HttpClientConfig
.Builder(Arrays.asList(urls))
.multiThreaded(true)
.defaultMaxTotalConnectionPerRoute(Integer.valueOf(maxTotal))
.maxTotalConnection(Integer.valueOf(perTotal))
.build());
this.client = factory.getObject();
基本操作
//创建索引
client.execute(new CreateIndex.Builder(index).build());
//创建 type
PutMapping.Builder builder = new PutMapping.Builder(index, type, mapping);
JestResult jestResult = client.execute(builder.build());
if (!jestResult.isSucceeded()) {
//失败
}
//删除索引
client.execute(new DeleteIndex.Builder(index).build());
操作
/**
* 获取对象
* 可以加路由:setParameter(Parameters.ROUTING, "")
*/
public T getData(String index, String type, String _id, Class clazz) {
Get get = new Get.Builder(index, _id).type(type).build();
JestResult result = client.execute(get);
if (result.isSucceeded()) {
return result.getSourceAsObject(clazz);
}
}
/**
* 写入数据
* 对象里要有 id
*/
public void insertData(String index, String type, List list) {
Index action = new Index.Builder(list).index(index).type(type).build();
try {
client.execute(action);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 功能描述:插入数据
* @entity 里面最好有@JestId id,要不然会自动生成一个
*/
public void insertData(String index, String type, T entity) {
Index action = new Index.Builder(entity).index(index).type(type).build();
try {
client.execute(action);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 功能描述:批量插入数据
* @param index 索引名
* @param type 类型
* @param dataList 批量数据
*/
public void bulkInsertData(String index, String type, List dataList) throws Exception{
List actions = new ArrayList<>();
assert dataList != null;
dataList.forEach(item -> {
actions.add(new Index.Builder(item).build());
});
Bulk bulk = new Bulk.Builder()
.defaultIndex(index)
.defaultType(type)
.addAction(actions)
.build();
client.execute(bulk);
}
异步操作
//异步写入
/**
* 功能描述:插入数据
*
* @param index 索引名
* @param type 类型
* @entity 里面最好有 id,要不然会自动生成一个
*/
public void insertDataAsync(String index, String type, T entity) {
Index action = new Index.Builder(entity).index(index).type(type).build();
client.executeAsync(action, new JestResultHandler() {
@Override
public void completed(JestResult result) {
logger.debug("insert success");
}
@Override
public void failed(Exception e) {
e.printStackTrace();
}
});
}
/**
* 功能描述:异步更新数据
*/
public void updateDataAsync(String index, String type, String _id, T entity) {
client.executeAsync(new Update.Builder(entity).id(_id)
.index(index)
.type(type)
.build(), new JestResultHandler() {
@Override
public void completed(JestResult result) {
logger.debug("insert success");
}
@Override
public void failed(Exception e) {
e.printStackTrace();
}
});
}
/**
* 功能描述:异步批量插入数据
*/
public void bulkInsertData(String index, String type, List dataList) throws Exception{
List actions = new ArrayList<>();
assert dataList != null;
dataList.forEach(item -> {
actions.add(new Index.Builder(item).build());
});
Bulk bulk = new Bulk.Builder()
.defaultIndex(index)
.defaultType(type)
.addAction(actions)
.build();
client.execute(bulk);
}
搜索
如果使用 sourcebuilder,需要引入 es 的包
org.elasticsearch
elasticsearch
5.5.3
compile
搜索代码:
/**
* 功能描述:搜索
* @param index 索引名
* @param type 类型
* @param constructor 查询构造
*/
public Page search(String index, String type, Class clazz, ESQueryBuilderConstructor constructor) {
Page page = new Page<>();
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//sourceBuilder.query(QueryBuilders.matchAllQuery());
sourceBuilder.query(constructor.listBuilders());
sourceBuilder.from((constructor.getFrom()));
sourceBuilder.size(constructor.getSize() > MAX_SIZE ? MAX_SIZE : constructor.getSize());
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//增加多个值排序
if (constructor.getSorts() != null) {
constructor.getSorts().forEach((key, value) -> {
sourceBuilder.sort(SortBuilders.fieldSort(key).order(value));
});
}
//设置需要返回的属性
if (constructor.getIncludeFields() != null || constructor.getExcludeFields() != null) {
sourceBuilder.fetchSource(constructor.getIncludeFields(), constructor.getExcludeFields());
}
logger.debug("查询条件:{}", sourceBuilder.toString());
//System.out.println("查询条件:" + sourceBuilder.toString());
Search search = new Search.Builder(sourceBuilder.toString())
.addIndex(index)
.addType(type).setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.build();
SearchResult result = null;
try {
result = client.execute(search);
} catch (IOException e) {
e.printStackTrace();
}
logger.debug("查询结果:{}", result.getJsonString());
List list = new ArrayList<>();
result.getHits(clazz).forEach(item -> {
list.add(item.source);
});
page.setList(list).setCount(result.getTotal());
return page;
}
统计
public Map
page对象:
public class Page implements Serializable {
private int pageSize;
public static final int COUNT_NOT_COUNT = -1;
public static final int PAGE_SIZE_NOT_PAGING = -1;
private int last;
private int first;
private int next;
private int prev;
private int pageNo;
private int centerNum;
private static final long serialVersionUID = 1L;
private String orderBy;
public static final int COUNT_ONLY_COUNT = -2;
private List list;
private long count;
public List getList() {
return this.list;
}
public int getPageSize() {
return this.pageSize;
}
public Page(int pageNo, int pageSize) {
this(pageNo, pageSize, 0L);
}
public void setOrderBy(String orderBy) {
this.orderBy = orderBy;
}
public Page(int pageNo, int pageSize, long count, List list) {
this.pageNo = 1;
this.pageSize = pageSize;
this.list = list;
this.centerNum = 5;
this.pageNo = pageNo;
this.pageSize = pageSize;
this.count = count;
if (list != null) {
this.list = list;
}
}
public int getFirstResult() {
int a = (this.getPageNo() - 1) * this.getPageSize();
if (this.getCount() != -1L && (long)a >= this.getCount()) {
a = 0;
}
return a;
}
public int getMaxResults() {
return this.getPageSize();
}
public long getCount() {
return this.count;
}
public void setPageSize(int pageSize) {
if (pageSize <= 0) {
this.pageSize = 20;
} else {
this.pageSize = pageSize;
}
}
public int getPageNo() {
return this.pageNo;
}
public void initialize() {
if (!this.isNotPaging() && !this.isNotCount() && !this.isOnlyCount()) {
if (this.pageSize <= 0) {
this.pageSize = 20;
}
this.first = 1;
this.last = (int)(this.count / (long)this.pageSize) + this.first - 1;
if (this.count % (long)this.pageSize != 0L || this.last == 0) {
++this.last;
}
if (this.last < this.first) {
this.last = this.first;
}
if (this.pageNo <= this.first) {
this.pageNo = this.first;
}
if (this.pageNo >= this.last) {
this.pageNo = this.last;
}
Page var10000;
if (this.pageNo > 1) {
var10000 = this;
this.prev = this.pageNo - 1;
} else {
var10000 = this;
this.prev = this.first;
}
if (var10000.pageNo < this.last - 1) {
this.next = this.pageNo + 1;
} else {
this.next = this.last;
}
}
}
public boolean isNotPaging() {
return this.pageSize == -1;
}
public Page() {
this.pageNo = 1;
this.pageSize = 10;
this.list = new ArrayList();
this.centerNum = 5;
}
public void setCount(long count) {
if ((this.count = count) != -1L && (long)this.pageSize >= count) {
this.pageNo = 1;
}
}
public boolean isOnlyCount() {
return this.count == -2L;
}
public Page(int pageNo, int pageSize, long count) {
this(pageNo, pageSize, count, (List)null);
}
public boolean isNotCount() {
return this.count == -1L || this.isNotPaging();
}
public Page setList(List list) {
if (list == null) {
list = new ArrayList();
}
this.list = (List)list;
return this;
}
public void setCenterNum(int centerNum) {
this.centerNum = centerNum;
}
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
}
}
总结:使用 jest 的 client 还是比较方便的,并且使用@JestId 注解,直接将对象的 id 作为 doc 的 id。性能上也不错,经本人测试 1 秒 5k-6k 数据写入没问题