SpringBoot整合Elasticsearch
SpringBoot整合Elasticsearch有以下几种方式:
- 使用官方的Elasticsearch Java客户端进行集成
- 通过添加Elasticsearch Java客户端的依赖,可以直接在Spring Boot应用中使用原生的Elasticsearch API进行操作。
- 参考文档
- 使用Spring Data Elasticsearch进行集成
- Spring Data Elasticsearch是Spring Data项目的一部分,提供了更高级的抽象和易用性,可以简化与Elasticsearch的交互。
- 通过添加Spring Data Elasticsearch的依赖,可以使用Repository接口和注解来定义和执行CRUD操作。
- 官方文档
本文使用第一种方式。使用官方推荐的RestHighLevelClient操作ES。由于版本兼容问题,请选择和Elasticsearch对应的Java客户端版本。
依赖
从官方文档可以知道需要导入org.elasticsearch:elasticsearch和org.elasticsearch.client:elasticsearch-rest-client。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.4.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.4.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
配置
@Configuration
public class ESConfig {
/**
* 解决netty引起的issue
*/
@PostConstruct
void init() {
System.setProperty("es.set.netty.runtime.available.processors", "false");
}
@Bean
public RestHighLevelClient getRestClient() {
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient
.builder(new HttpHost("192.168.200.200", 9200, "http")));
return restHighLevelClient;
}
}
测试
创建索引
@Autowired
private RestHighLevelClient restHighLevelClient;
/**
* 创建索引
*/
@Test
public void createIndex1() {
String result = "创建成功";
CreateIndexRequest createIndexRequest = new CreateIndexRequest("stu");
try {
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
if (!createIndexResponse.isAcknowledged()){
result = "创建失败";
}else{
result = "索引已经存在";
}
} catch (IOException e) {
e.printStackTrace();
result = "接口异常";
}
System.out.println(result);
}
/**
* 创建索引同时创建映射关系
* 如索引存在:新增文档数据;如果索引不存在:创建一条索引
*/
@Test
public void createIndex2() {
HashMap<String, Object> map = new HashMap<>();
map.put("user", "kimchyrw");
map.put("postDate", new Date());
map.put("message", "trying out Elasticsearch");
IndexRequest request = new IndexRequest("posts")
.id("2").source(map, XContentType.JSON);
try {
//响应信息
IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);
String index = indexResponse.getIndex();
String id = indexResponse.getId();
System.out.println("index: " + index + " id: " + id);
//创建索引还是更新索引
if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
System.out.println("CREATED.....");
} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
System.out.println("UPDATED....");
}
//校验分片信息
ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()){
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure :shardInfo.getFailures()) {
String reason = failure.reason();
System.out.println("reason: " + reason);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
更新文档中的数据
/**
* 更新一行数据
*/
@Test
public void updateDoc() {
//更新的数据
HashMap<String, Object> map = new HashMap<>();
map.put("updated", new Date());
map.put("user", "kimchyrw");
map.put("reason", "daily update");
UpdateRequest updateRequest = new UpdateRequest("posts", "2")
.doc(map);
try {
UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
String index = updateResponse.getIndex();
String id = updateResponse.getId();
long version = updateResponse.getVersion();
if (updateResponse.getResult() == DocWriteResponse.Result.CREATED) {
System.out.println("CREATED");
} else if (updateResponse.getResult() == DocWriteResponse.Result.UPDATED) {
System.out.println("UPDATED");
} else if (updateResponse.getResult() == DocWriteResponse.Result.DELETED) {
System.out.println("DELETED");
} else if (updateResponse.getResult() == DocWriteResponse.Result.NOOP) {
System.out.println("NOOP");
}
} catch (IOException e) {
e.printStackTrace();
}
}
查询
/**
* 根据id查询document
*/
@Test
public void getApi() {
GetRequest getRequest = new GetRequest("posts", "1");
//可选参数
//禁用源检索,默认启用,开启后检索不到数据
// getRequest.fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE);
try {
GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
String index = getResponse.getIndex();
String id = getResponse.getId();
System.out.println("index: " + index + " id: " + id);
if (getResponse.isExists()) {
long version = getResponse.getVersion();
String sourceAsString = getResponse.getSourceAsString();
Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();
byte[] sourceAsBytes = getResponse.getSourceAsBytes();
System.out.println("version: " + version);
System.out.println("sourceAsMap: " + sourceAsMap);
System.out.println("sourceAsBytes: " + Arrays.toString(sourceAsBytes));
System.out.println("sourceAsString: " + sourceAsString);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根据指定字段查询document
*/
@Test
public void testSearch2() {
SearchRequest searchRequest = new SearchRequest("posts");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//根据指定字段查询
searchSourceBuilder.query(QueryBuilders.termQuery("user", "kimchy"));
//分页查询记录
searchSourceBuilder.from(0);
searchSourceBuilder.size(5);
//设置超时时间
// searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//按字段排序或者按评分排序
searchSourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));
searchSourceBuilder.sort(new FieldSortBuilder("_id").order(SortOrder.ASC));
//结果高亮
//查询部分字段
searchSourceBuilder.fetchSource(new String[]{"user"}, new String[]{"user1"});
searchRequest.source(searchSourceBuilder);
try {
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
RestStatus status = searchResponse.status();
TimeValue took = searchResponse.getTook();
Boolean terminatedEarly = searchResponse.isTerminatedEarly();
boolean timedOut = searchResponse.isTimedOut();
SearchHits hits = searchResponse.getHits();
TotalHits totalHits = hits.getTotalHits();
long numHits = totalHits.value;
TotalHits.Relation relation = totalHits.relation;
float maxScore = hits.getMaxScore();
System.out.println("hits: " + hits + " totalHits: " + totalHits + " numHits: " + numHits + " maxScore: " + maxScore);
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit: searchHits) {
String id = hit.getId();
System.out.println("id: " + id);
String sourceAsString = hit.getSourceAsString();
System.out.println(sourceAsString);
}
} catch (IOException e) {
e.printStackTrace();
}
}
参考
- Rest High Level Client文档
- Spring Data Elasticsearch - Reference Documentation