Java封装Elasticsearch8常用接口方法(二)
书接上文 Java封装Elasticsearch8常用接口方法(一)
2.1索引相关操作
2.1.1 创建索引
创建索引
/**
* 创建索引
*
* @param indexName
* @return
* @throws Exception
*/
public boolean createIndex(String indexName) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
//创建索引并返回状态
CreateIndexResponse createIndexResponse = client
.indices()
.create(c -> c
.index(indexName)
);
Boolean acknowledged = createIndexResponse.acknowledged();
System.out.println("acknowledged = " + acknowledged);
ESClientPool.returnClient(client);
return acknowledged;
}
创建索引 指定映射
/**
* 创建索引 指定映射
*
* @param indexName
* @param documentMap
* @return
* @throws Exception
*/
public boolean createIndex(String indexName, Map<String, Property> documentMap) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
CreateIndexResponse createIndexResponse = client
.indices()
.create(createIndexBuilder -> createIndexBuilder
.index(indexName)
.mappings(mappings ->
mappings.properties(documentMap))
//.aliases("User", aliases -> aliases.isWriteIndex(true))
);
Boolean acknowledged = createIndexResponse.acknowledged();
System.out.println("acknowledged = " + acknowledged);
ESClientPool.returnClient(client);
return acknowledged;
}
/**
* documentMap写法,参数与实际的es脚本基本一致
* @return
*/
public Map<String, Property> document(){
Map<String, Property> documentMap = new HashMap<>();
documentMap.put("userName", Property.of(property ->
property.text(TextProperty.of(textProperty ->
textProperty.index(true).analyzer("ik_max_word"))
)
)
);
documentMap.put("age", Property.of(property ->
property.integer(IntegerNumberProperty.of(integerNumberProperty
-> integerNumberProperty.index(true))
)
)
);
return documentMap;
}
2.1.2 删除索引
删除前校验索引是否存在,可看下2.1.4索引存在校验
/**
* 删除索引
*/
public boolean deleteIndex(String indexName) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
boolean exists = exists(client, indexName);
if (!exists) {
//不存在就结束
return false;
}
DeleteIndexResponse deleteIndexResponse = client
.indices()
.delete(index -> index
.index(indexName)
);
boolean acknowledged = deleteIndexResponse.acknowledged();
ESClientPool.returnClient(client);
System.out.println("acknowledged = " + acknowledged);
return acknowledged;
}
/**
* 删除索引 批量
*/
public boolean deleteIndex(List<String> indexName) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
boolean exists = exists(client, indexName);
if (!exists) {
//不存在就结束
return false;
}
DeleteIndexResponse deleteIndexResponse = client
.indices()
.delete(index
-> index.index(indexName)
);
boolean acknowledged = deleteIndexResponse.acknowledged();
ESClientPool.returnClient(client);
System.out.println("acknowledged = " + acknowledged);
return acknowledged;
}
2.1.3 查看索引
/**
* 查看索引信息
*
* @param indexName
* @return
* @throws Exception
*/
public Map<String, IndexState> getIndexMsg(String indexName) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
GetIndexResponse getIndexResponse = client
.indices()
.get(getIndex -> getIndex
.index(indexName)
);
Map<String, IndexState> result = getIndexResponse.result();
ESClientPool.returnClient(client);
return result;
}
/**
* 查看所有索引信息
*
* @return
* @throws Exception
*/
public List<IndicesRecord> getAllIndex() throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
IndicesResponse indicesResponse = client
.cat()
.indices();
ESClientPool.returnClient(client);
return indicesResponse.valueBody();
}
2.1.4 索引存在校验
/**
* 索引是否存在
*
* @param client
* @param indexName
* @return
*/
public boolean exists(ElasticsearchClient client, String indexName) throws Exception {
boolean value = client
.indices()
.exists(e -> e
.index(indexName)
).value();
System.out.println("indexexists: " + value);
return value;
}
public boolean exists(ElasticsearchClient client, List<String> indexName) throws Exception {
boolean value = client
.indices()
.exists(e -> e
.index(indexName)
).value();
System.out.println("indexexists: " + value);
return value;
}
2.2 别名操作
官方释义: 索引别名可以指向一个或多个索引,并且可以在任何需要索引名称的API中使用。 别名为我们提供了极大的灵活性。它们允许我们执行以下操作:
1)在正在运行的集群上的一个索引和另一个索引之间透明切换;
2)对多个索引进行分组组合(例如,lastthreemonths的索引别名:是过去3个月索引 logstash201903, logstash201904, logstash_201905的组合);
3)在索引中的文档子集上创建“视图”(结合业务场景,会提升检索效率)。
通俗解释: 索引别名类似:windows的快捷方式,linux的软链接,mysql的视图。
前提:Elasitcsearch创建索引后,索引名不允许改。很多业务场景下单一索引可能无法满足要求。
场景1:PB级别增量数据,借助rollover api实现,由基于日期的n个索引组成,显然,对外提供服务使用别名会很便捷。
场景2:试想,线上提供服务的某个索引出了问题,比如:某字段分词定义不准确,如何保证对外提供服务不停止(不更改业务代码)的前提下更换索引,显然,别名更合适。
注意:实际业务场景使用别名会很方便、灵活、快捷、业务松耦合!!
此处介绍引用铭毅天下大佬的文章 原文链接:https://blog.csdn.net/laoyang360/article/details/93693440
2.2.1 添加别名
/**
* 添加别名
*
* @param indexName 索引名称
* @param aliasName 别名名称
* @return
* @throws IOException
*/
public boolean addAliases(List<String> indexName, String aliasName) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
UpdateAliasesResponse updateAliasesResponse = client
.indices()
.updateAliases(update -> update
.actions(action -> action
.add(add -> add
.indices(indexName)
.alias(aliasName)
)
)
);
return updateAliasesResponse.acknowledged();
}
2.2.2 移除别名
/**
* 移除别名
*
* @param indexName
* @param aliasName
* @throws IOException
*/
public boolean removeAliases(List<String> indexName, String aliasName) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
DeleteAliasResponse deleteAliasResponse = client
.indices()
.deleteAlias(del -> del
.index(indexName)
.name(aliasName)
);
ESClientPool.returnClient(client);
return deleteAliasResponse.acknowledged();
}
2.2.3 重命名别名
本质上没有修改方法,实现上就是先删后插
/**
* 重命名别名,解除旧索引的别名,填加新索引的别名
*
* @param indexName
* @param newAliasName
* @param oldAliasName
* @throws IOException
*/
public boolean renameAliases(List<String> indexName, String newAliasName, String oldAliasName) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
DeleteAliasResponse deleteAliasResponse = null;
if (StringUtils.isNotBlank(oldAliasName)) {
deleteAliasResponse = client
.indices()
.deleteAlias(del -> del
.index(indexName)
.name(oldAliasName)
);
}
if (!deleteAliasResponse.acknowledged()) return false;
UpdateAliasesResponse updateAliasesResponse = client
.indices()
.updateAliases(update -> update
.actions(action -> action
.add(add -> add
.indices(indexName)
.alias(newAliasName)
)
)
);
ESClientPool.returnClient(client);
return updateAliasesResponse.acknowledged();
}
2.2.4 根据别名查询索引
/**
* 根据别名查询索引信息
*
* @param aliasName
* @throws IOException
*/
public Map<String, IndexAliases> getIndexMsgByAlias(String aliasName) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
GetAliasResponse getAliasResponse = client
.indices()
.getAlias(a -> a
.name(aliasName)
);
Map<String, IndexAliases> result = getAliasResponse.result();
return result;
}
/**
* 根据别名查询索引名称
*
* @param aliasName
* @throws IOException
*/
public List<String> getIndexListByAlias(String aliasName) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
GetAliasResponse getAliasResponse = client
.indices()
.getAlias(a -> a
.name(aliasName)
);
Map<String, IndexAliases> result = getAliasResponse.result();
List<String> indexList = new ArrayList<>();
if (!CollectionUtils.isEmpty(result)) {
indexList = result.keySet().stream().collect(Collectors.toList());
}
return indexList;
}
2.3 文档操作
2.3.1 添加文档信息
/**
* 添加文档信息
*
* @param indexName
* @param obj
* @throws IOException
*/
public long createDocument(String indexName, Object obj) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
IndexResponse indexResponse = client
.index(x -> x
.index(indexName)
.document(obj)
);
long version = indexResponse.version();
ESClientPool.returnClient(client);
return version;
}
/**
* 添加文档信息 指定id
*
* @param indexName
* @param obj
* @throws IOException
*/
public long createDocument(String indexName, String id, Object obj) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
IndexResponse indexResponse = client
.index(x -> x
.index(indexName)
.id(id)
.document(obj)
);
long version = indexResponse.version();
ESClientPool.returnClient(client);
return version;
}
2.3.2 修改文档属性
/**
* 修改文档自定义属性
*
* @param indexName
* @param id
* @param obj
* @return version
* @throws Exception
*/
public long updateDocument(String indexName, String id, Object obj) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
UpdateResponse<Object> userUpdateResponse = client
.update(x -> x
.index(indexName)
.id(id)
.doc(obj), Object.class);
long version = userUpdateResponse.version();
ESClientPool.returnClient(client);
return version;
}
2.3.3 批量操作
2.3.3.1 批量插入
/**
* bulk批量插入
*
* @param indexName
* @param objList
* @return List<BulkResponseItem>
* @throws Exception
*/
public List<BulkResponseItem> bulkInsert(String indexName, List<Object> objList) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
//创建BulkOperation列表准备批量插入doc
List<BulkOperation> bulkOperations = new ArrayList<>();
//将user中id作为es id,也可不指定id es会自动生成id
objList.forEach(doc -> bulkOperations
.add(BulkOperation
.of(b -> b
.index(c -> c
.document(doc)
)
)
)
);
BulkResponse bulk = client
.bulk(x -> x
.index(indexName)
.operations(bulkOperations)
);
List<BulkResponseItem> items = bulk.items();
ESClientPool.returnClient(client);
return items;
}
/**
* bulk批量插入 指定id
*
* @param indexName
* @param idList id顺序要与实体数据顺序对应
* @param objList
* @return List<BulkResponseItem>
* @throws Exception
*/
public List<BulkResponseItem> bulkInsert(String indexName, List<String> idList, List<Object> objList) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
//创建BulkOperation列表准备批量插入doc
List<BulkOperation> bulkOperations = new ArrayList<>();
//将id作为es id,也可不指定id es会自动生成id
for (int i = 0; i < objList.size(); i++) {
int finalI = i;
bulkOperations.add(BulkOperation
.of(b -> b
.index(c -> c
.id(idList.get(finalI))
.document(objList.get(finalI)
)
)
)
);
}
BulkResponse bulk = client
.bulk(x -> x
.index(indexName)
.operations(bulkOperations)
);
List<BulkResponseItem> items = bulk.items();
ESClientPool.returnClient(client);
return items;
}
2.3.3.2 批量删除文档记录
/**
* bulk批量删除文档记录
*
* @param indexName
* @param documentId
* @return List<BulkResponseItem>
* @throws Exception
*/
public List<BulkResponseItem> delDocByIds(String indexName, List<String> documentId) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
// 构建批量操作对象BulkOperation的集合
List<BulkOperation> bulkOperations = new ArrayList<>();
// 向集合中添加需要删除的文档id信息
for (int i = 0; i < documentId.size(); i++) {
int finalI = i;
bulkOperations.add(BulkOperation.of(b -> b
.delete((d -> d
.index(indexName)
.id(documentId.get(finalI)
)
))
));
}
// 调用客户端的bulk方法,并获取批量操作响应结果
BulkResponse response = client
.bulk(e -> e
.index(indexName)
.operations(bulkOperations));
return response.items();
}
2.3.3.3 批量更新数据
这个方法还没有实际测试过,总体问题应该不大
/**
* bluk批量更新数据
*
* @param indexName
* @param idList
* @param objList
* @return List<BulkResponseItem> items
* @throws Exception
*/
public List<BulkResponseItem> bulkUpdate(String indexName, List<String> idList, List<Object> objList) throws Exception {
ElasticsearchClient client = ESClientPool.getClient();
//创建BulkOperation列表准备批量插入doc
List<BulkOperation> bulkOperations = new ArrayList<>();
//将id作为es id,也可不指定id es会自动生成id
for (int i = 0; i < objList.size(); i++) {
int finalI = i;
//TODO 没测试不知对不对
bulkOperations.add(BulkOperation.of(b -> b
.update(u -> u
.index(indexName)
.id(idList.get(finalI))
.action(a -> a
.doc(objList.get(finalI))
))
));
}
BulkResponse bulk = client
.bulk(x -> x
.index(indexName)
.operations(bulkOperations));
List<BulkResponseItem> items = bulk.items();
ESClientPool.returnClient(client);
return items;
}
代码都是实际使用到才整理出来的,如有写错或者不理解的地方可以相互交流。共同进步~
下篇文章分享各种查询~