Springboot项目如何使用Elasticsearch
用的是阿里云elasticsearch集群,所以需要初始化连接代码。
- 导入Maven依赖
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.9.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.17.16</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.12.3</version>
</dependency>
- 编写elasticsearch方法工具类
@Slf4j
@Component
public class ElasticSearchServiceImpl implements IElasticSearchService {
private ElasticsearchClient elasticsearchClient;
@PostConstruct
private void init(){
log.info("初始化es链接信息");
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
String userName = "***";
String password = "******";
String url = "***.public.elasticsearch.aliyuncs.com";
final int maxConnTotal = 200;
final int maxConnPerRoute = 50;
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
RestClient restClient = RestClient.builder(new HttpHost(url, 9200, "http"))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.setMaxConnTotal(maxConnTotal);
httpClientBuilder.setMaxConnPerRoute(maxConnPerRoute);
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
}).build();
ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
this.elasticsearchClient = new ElasticsearchClient(transport);
log.info("初始化es链接信息完毕");
}
@Override
public <T> void indexDocments(String indexName, String id, T document) {
Assert.isBlank(indexName,"es索引名称不能为空");
Assert.isBlank(id,"es索引名称id不能为空");
Assert.isNull(document,"es索引名称实体内容不能为空");
try {
elasticsearchClient.index(i -> i
.index(indexName)
.id(id)
.document(document)
);
} catch (IOException e) {
log.error("elastic search indexDocments error:",e);
}
}
@Override
public <T> List<Boolean> bulkIndexDocuments(String indexName, List<String> idList, List<T> documents) {
Assert.isBlank(indexName,"es索引名称不能为空");
Assert.isTrue(CollUtil.isEmpty(idList),"es索引名称id列表不能为空");
Assert.isNull(CollUtil.isEmpty(documents),"es索引名称实体内容列表不能为空");
BulkRequest.Builder br = new BulkRequest.Builder();
List<Boolean> resultList = new ArrayList<>();
for (int i=0;i<documents.size();i++) {
int finalI = i;
br.operations(op -> op
.index(idx -> idx
.index(indexName)
.id(idList.get(finalI))
.document(documents.get(finalI))
)
);
}
try {
BulkResponse result = elasticsearchClient.bulk(br.build());
for (BulkResponseItem item: result.items()) {
if (item.error() != null) {
resultList.add(false);
log.error("批量插入es文档单个错误:"+item.error().reason());
}else{
resultList.add(true);
}
}
} catch (IOException e) {
log.error("批量插入es文档失败:",e);
}
return resultList;
}
@Override
public <T> T searchDocumentsById(String indexName, String id, Class<T> clz) {
Assert.isBlank(indexName,"es索引名称不能为空");
Assert.isBlank(id,"es索引名称id不能为空");
Assert.isNull(clz,"es索引名称实体类型不能为空");
T document = null;
try {
GetResponse<T> response = elasticsearchClient.get(g -> g
.index(indexName)
.id(id), clz
);
if (response.found()) {
document = response.source();
}
} catch (IOException e) {
log.error("根据id[{}]查询es文档失败:", id, e);
}
return document;
}
@Override
public <T> ElasticSearchPageResult<T> pageDocumentsWithSingleFiled(String indexName, String fieldName, String fieldValue, Integer page, Integer size, Class<T> clz) {
Assert.isBlank(indexName,"es索引名称不能为空");
Assert.isBlank(fieldName,"es查询字段名称不能为空");
Assert.isBlank(fieldValue,"es查询字段内容不能为空");
Assert.isNull(page,"es分页查询页码不能为空");
Assert.isNull(size,"es分页查询页大小不能为空");
Assert.isNull(clz,"es索引名称实体类型不能为空");
ElasticSearchPageResult<T> elasticSearchPageResult = new ElasticSearchPageResult<>();
try {
SearchResponse<T> response = elasticsearchClient.search(s -> s
.index(indexName)
.query(q -> q
.match(t -> t
.field(fieldName)
.query(fieldValue)
)
).from((page-1)*size).size(size),
clz
);
TotalHits total = response.hits().total();
if(total.value() > 0){
List<T> documentList = new ArrayList<>();
elasticSearchPageResult.setTotalHits(total.value());
List<Hit<T>> hits = response.hits().hits();
for (Hit<T> hit: hits) {
documentList.add(hit.source());
}
elasticSearchPageResult.setRecords(documentList);
}
} catch (IOException e) {
log.error("查询es文档失败",e);
}
return elasticSearchPageResult;
}
@Override
public <T> ElasticSearchPageResult<T> pageDocuments(String indexName, Integer page, Integer size, Class<T> clz) {
Assert.isBlank(indexName,"es索引名称不能为空");
Assert.isNull(page,"es分页查询页码不能为空");
Assert.isNull(size,"es分页查询页大小不能为空");
Assert.isNull(clz,"es索引名称实体类型不能为空");
ElasticSearchPageResult<T> elasticSearchPageResult = new ElasticSearchPageResult<>();
try {
SearchResponse<T> response = elasticsearchClient.search(s -> s
.index(indexName)
.query(q -> q
.matchAll(t -> t)
)
.sort(so -> so
.field(f -> f
.field("id")
.order(SortOrder.Desc)
)
)
.from((page-1)*size).size(size),
clz
);
TotalHits total = response.hits().total();
if(total.value() > 0){
List<T> documentList = new ArrayList<>();
elasticSearchPageResult.setTotalHits(total.value());
List<Hit<T>> hits = response.hits().hits();
for (Hit<T> hit: hits) {
documentList.add(hit.source());
}
elasticSearchPageResult.setRecords(documentList);
}
} catch (IOException e) {
log.error("查询es文档失败",e);
}
return elasticSearchPageResult;
}
@Override
public List<Boolean> bulkDeleteDocuments(String indexName, List<String> idList){
Assert.isBlank(indexName,"es索引名称不能为空");
Assert.isTrue(CollUtil.isEmpty(idList),"es索引名称id列表不能为空");
BulkRequest.Builder br = new BulkRequest.Builder();
List<Boolean> resultList = new ArrayList<>();
for (String id : idList) {
br.operations(op -> op
.delete(del -> del
.index(indexName)
.id(id)
)
);
}
try {
BulkResponse result = elasticsearchClient.bulk(br.build());
for (BulkResponseItem item : result.items()) {
if (item.error() != null) {
resultList.add(false);
log.error("批量删除es文档单个错误:{}", item.error().reason());
} else {
resultList.add(true);
}
}
} catch (IOException e) {
log.error("批量删除es文档失败:", e);
}
return resultList;
}
@Override
public <T> ElasticSearchPageResult<T> pageDocumentContainEqFieldList(String indexName, String fieldName, String fieldValue, Integer page, Integer size, Class<T> clz) {
Assert.isBlank(indexName, "es索引名称不能为空");
Assert.isBlank(fieldName, "es查询字段名称不能为空");
Assert.isBlank(fieldValue, "es查询字段内容不能为空");
Assert.isNull(page, "es分页查询页码不能为空");
Assert.isNull(size, "es分页查询页大小不能为空");
Assert.isNull(clz, "es索引名称实体类型不能为空");
ElasticSearchPageResult<T> elasticSearchPageResult = new ElasticSearchPageResult<>();
try {
SearchResponse<T> response = elasticsearchClient.search(s -> s
.index(indexName)
.query(q -> q
.queryString(qs -> qs
.defaultField(fieldName)
.query("\"" + fieldValue + "\"")
)
).from((page - 1) * size).size(size),
clz
);
TotalHits total = response.hits().total();
if (total.value() > 0) {
List<T> documentList = new ArrayList<>();
elasticSearchPageResult.setTotalHits(total.value());
List<Hit<T>> hits = response.hits().hits();
for (Hit<T> hit : hits) {
documentList.add(hit.source());
}
elasticSearchPageResult.setRecords(documentList);
}
} catch (IOException e) {
log.error("查询es文档失败", e);
}
return elasticSearchPageResult;
}
@Override
public <T> ElasticSearchPageResult<T> pageCustomizeDocumentList(EsPageCustomizeQueryDTO esQuery, Function<Query.Builder, ObjectBuilder<Query>> queryCondition, Class<T> clz) {
Assert.isBlank(esQuery.getIndexName(), "es索引名称不能为空");
Assert.isNull(queryCondition, "es查询条件不能为空");
Assert.isNull(esQuery.getFrom(), "es分页查询页码不能为空");
Assert.isNull(esQuery.getSize(), "es分页查询页大小不能为空");
Assert.isNull(clz, "es索引名称实体类型不能为空");
ElasticSearchPageResult<T> elasticSearchPageResult = new ElasticSearchPageResult<>();
try {
SearchResponse<T> response = elasticsearchClient.search(s -> s
.index(esQuery.getIndexName())
.query(queryCondition)
.from((esQuery.getFrom() - 1) * esQuery.getSize())
.size(esQuery.getSize()),
clz
);
TotalHits total = response.hits().total();
if (total.value() > 0) {
List<T> documentList = new ArrayList<>();
elasticSearchPageResult.setTotalHits(total.value());
List<Hit<T>> hits = response.hits().hits();
for (Hit<T> hit : hits) {
documentList.add(hit.source());
}
elasticSearchPageResult.setRecords(documentList);
}
} catch (IOException e) {
log.error("查询es文档失败", e);
}
return elasticSearchPageResult;
}
}