第一步,开启本地的 ElasticSearch
启动 elasticSearch.bat
npm run start (head 插件)
第二步,在 Spring Boot 项目中引入依赖
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.6.1</version>
</dependency>
第三步,配置 yml 和 配置类
# ES
elasticsearch:
host: 127.0.0.1
port: 9200
username: # 若 ES 无账号密码,可不填
password: # 若 ES 无账号密码,可不填
connectTimeout: 5000 # 连接超时(毫秒)
socketTimeout: 30000 # 读写超时(毫秒)
maxConnTotal: 100 # 最大连接数
maxConnPerRoute: 10 # 单路由最大连接数
java
package com.wf.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ElasticsearchConfig {
@Value("${elasticsearch.host}")
private String host;
@Value("${elasticsearch.port}")
private int port;
@Value("${elasticsearch.username}")
private String username;
@Value("${elasticsearch.password}")
private String password;
@Value("${elasticsearch.connectTimeout}")
private int connectTimeout;
@Value("${elasticsearch.socketTimeout}")
private int socketTimeout;
@Value("${elasticsearch.maxConnTotal}")
private int maxConnTotal;
@Value("${elasticsearch.maxConnPerRoute}")
private int maxConnPerRoute;
@Bean
public RestHighLevelClient restHighLevelClient() {
// 构建 RestClient
RestClientBuilder builder = RestClient.builder(
new HttpHost(host, port, "http")
)
.setRequestConfigCallback(requestConfigBuilder -> {
requestConfigBuilder.setConnectTimeout(connectTimeout);
requestConfigBuilder.setSocketTimeout(socketTimeout);
return requestConfigBuilder;
})
.setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.setMaxConnTotal(maxConnTotal);
httpClientBuilder.setMaxConnPerRoute(maxConnPerRoute);
return httpClientBuilder;
});
return new RestHighLevelClient(builder);
}
}
第四步,实现实体类
java
package com.wf.dao.ESPojo;
import lombok.Data;
@Data
public class ESArticle {
private String id; // ES 文档 ID
private String title; // 标题(测试 IK 分词)
private String content; // 内容(测试 IK 分词)
private Long createTime; // 在 ES 中的时间
private String summary;//概述
private Integer viewCounts;//浏览次数
private String author;//作者
}
第五步,实现 Service
java
package com.wf.service;
import com.alibaba.fastjson.JSON;
import com.wf.dao.ESPojo.ESArticle;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Service
public class ArticleEsService {
@Resource
private RestHighLevelClient restHighLevelClient;
private static final String INDEX_NAME = "article_index"; // 索引名
//ik 分词器
public List<ESArticle> searchByKeyword(String keyword) throws IOException {
SearchRequest request = new SearchRequest(INDEX_NAME);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 构建 match 查询:默认对 "title" 和 "content" 分词搜索(可指定字段)
MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("title", keyword)
.analyzer("ik_max_word"); // 明确指定分词器(或依赖 mapping 配置)
sourceBuilder.query(matchQuery);
request.source(sourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
// 解析结果
List<ESArticle> result = new ArrayList<>();
for (SearchHit hit : response.getHits().getHits()) {
result.add(JSON.parseObject(hit.getSourceAsString(), ESArticle.class));
}
return result;
}
// 创建索引(含 IK 分词配置)
public boolean createIndex() throws IOException {
CreateIndexRequest request = new CreateIndexRequest(INDEX_NAME);
// 配置 mapping(指定 IK 分词)
XContentBuilder mapping = XContentFactory.jsonBuilder()
.startObject()
.startObject("properties")
// title 字段:索引用 ik_max_word,搜索用 ik_smart
.startObject("title")
.field("type", "text")
.field("analyzer", "ik_max_word")
.field("search_analyzer", "ik_smart")
.endObject()
// content 字段:同上
.startObject("content")
.field("type", "text")
.field("analyzer", "ik_max_word")
.field("search_analyzer", "ik_smart")
.endObject()
// summary 概述字段
.startObject("content")
.field("type", "text")
.field("analyzer", "ik_max_word")
.field("search_analyzer", "ik_smart")
.endObject()
// author
.startObject("author")
.field("type","text")
.field("analyzer","ik_max_word")
.field("search_analyzer","ik_smart")
.endObject()
// createTime 字段
.startObject("createTime")
.field("type", "long")
.endObject()
.endObject()
.endObject();
request.mapping(String.valueOf(mapping));
// 执行创建
CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
return response.isAcknowledged();
}
// 判断索引是否存在
public boolean existsIndex() throws IOException {
IndicesExistsRequest request = new IndicesExistsRequest(INDEX_NAME);
// return restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
return true;
}
// 删除索引
public boolean deleteIndex() throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest(INDEX_NAME);
return restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT).isAcknowledged();
}
// 新增文档
public String addDocument(ESArticle article) throws IOException {
IndexRequest request = new IndexRequest(INDEX_NAME)
.id(article.getId()) // 自定义 ID,若不填则 ES 自动生成
.source(JSON.toJSONString(article), XContentType.JSON);
IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
return response.getId(); // 返回 ES 生成的 ID(若自定义则和入参一致)
}
// 修改文档(根据 ID 更新)
public boolean updateDocument(ESArticle article) throws IOException {
UpdateRequest request = new UpdateRequest(INDEX_NAME, article.getId())
.doc(JSON.toJSONString(article), XContentType.JSON);
UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
return response.getResult() != null;
}
// 删除文档(根据 ID 删除)
public boolean deleteDocument(String docId) throws IOException {
DeleteRequest request = new DeleteRequest(INDEX_NAME, docId);
DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
return response.getResult() != null;
}
// 查询文档(根据 ID 查询)
public ESArticle getDocument(String docId) throws IOException {
GetRequest request = new GetRequest(INDEX_NAME, docId);
GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
if (response.isExists()) {
return JSON.parseObject(response.getSourceAsString(), ESArticle.class);
}
return null;
}
}
第六步,测试
java
@Resource
private ArticleEsService articleEsService;
// 测试创建索引
@Test
void testCreateIndex() throws IOException {
boolean success = articleEsService.createIndex();
System.out.println("创建索引结果:" + success); // 期望 true
}
// 测试新增文档
@Test
void testAddDocument() throws IOException {
ESArticle article = new ESArticle();
article.setId("1");
article.setTitle("Spring Boot 集成 Elasticsearch 7.6.1");
article.setContent("详细讲解如何在 Spring Boot 中使用 Elasticsearch,包含 IK 分词验证...");
article.setCreateTime(System.currentTimeMillis());
String docId = articleEsService.addDocument(article);
System.out.println("新增文档 ID:" + docId); // 期望 "1"
}
// 测试分词查询(验证 IK)
@Test
void testSearchByKeyword() throws IOException {
List<ESArticle> articles = articleEsService.searchByKeyword("Spring Boot");
System.out.println("查询结果:" + articles.size()); // 期望 1
articles.forEach(System.out::println);
}
使用 head 查看创建情况
