SpringBoot集成Elasticsearch | Elasticsearch 7.x专属HLRC(High Level Rest Client)
- 前言
-
- [1. 版本说明与Maven依赖](#1. 版本说明与Maven依赖)
- [2. 配置文件(application.yml)](#2. 配置文件(application.yml))
- [3. 核心代码实现](#3. 核心代码实现)
-
- [3.1 配置类(构建HLRC客户端)](#3.1 配置类(构建HLRC客户端))
- [3.2 工具类(封装ES操作)](#3.2 工具类(封装ES操作))
- [3.3 实体类(Employee7xHlrc)](#3.3 实体类(Employee7xHlrc))
- [3.4 Controller层(测试接口)](#3.4 Controller层(测试接口))
- [4. 测试步骤](#4. 测试步骤)
SpringBoot集成Elasticsearch的三种核心方式,
Spring官方场景启动器、
Elasticsearch 7.x专属HLRC(High Level Rest Client)
Elasticsearch 8.x专属Java Client。
前言
Elasticsearch 7.x专属HLRC(High Level Rest Client)
HLRC是ES 7.x官方唯一推荐的高级客户端,稳定性与兼容性最优,支持所有ES 7.x特性,且版本需与ES服务器完全一致
1. 版本说明与Maven依赖
xml
<dependencies>
<!-- Web依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- FastJSON -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<!-- 1. Elasticsearch核心依赖(版本与ES服务器一致) -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.15.2</version>
</dependency>
<!-- 2. HLRC底层依赖(低级REST客户端) -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.15.2</version>
</dependency>
<!-- 3. HLRC核心依赖(高级REST客户端) -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.15.2</version>
</dependency>
</dependencies>
2. 配置文件(application.yml)
配置ES连接信息、超时时间、连接池参数(7.x默认未开启安全认证)。
yaml
server:
port: 8082 # 与方式一区分端口
# ES HLRC配置
elasticsearch:
hlrc:
cluster-name: es-cluster-7x # 集群名称(非必需,仅标识)
hosts: 127.0.0.1:9200 # 服务器地址(集群用逗号分隔)
scheme: http # 协议(7.x默认http,8.x默认https)
# 安全认证(7.x默认关闭,开启需配置)
# username: elastic
# password: 你的ES密码
# 超时配置(毫秒)
connect-timeout: 1000
socket-timeout: 30000
connection-request-timeout: 500
# 连接池配置
max-connect-num: 100 # 总连接数
max-connect-per-route: 50 # 单个节点最大连接数
3. 核心代码实现
3.1 配置类(构建HLRC客户端)
通过@ConfigurationProperties绑定配置,构建单例RestHighLevelClient(由Spring管理,避免重复创建连接)。
java
package com.es.demo.config;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
/**
* ES 7.x HLRC客户端配置类
*/
@Slf4j
@Data
@Configuration
@ConfigurationProperties(prefix = "elasticsearch.hlrc")
public class Es7xHlrcConfig {
// 配置参数(与application.yml对应)
private String clusterName;
private String hosts;
private String scheme;
private String username;
private String password;
private int connectTimeout;
private int socketTimeout;
private int connectionRequestTimeout;
private int maxConnectNum;
private int maxConnectPerRoute;
/**
* 构建RestHighLevelClient实例(单例,Spring自动注入)
*/
@Bean(name = "es7xRestHighLevelClient")
public RestHighLevelClient restHighLevelClient() {
// 1. 解析ES服务器地址(host:port格式)
List<HttpHost> httpHostList = new ArrayList<>();
String[] hostArray = hosts.split(",");
for (String host : hostArray) {
String[] hostPort = host.split(":");
if (hostPort.length != 2) {
throw new RuntimeException("ES地址格式错误:" + host + "(正确格式:host:port)");
}
httpHostList.add(new HttpHost(hostPort[0], Integer.parseInt(hostPort[1]), scheme));
}
// 2. 构建RestClientBuilder
RestClientBuilder builder = RestClient.builder(httpHostList.toArray(new HttpHost[0]));
// 3. 配置安全认证(若开启)
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
if (username != null && password != null) {
credentialsProvider.setCredentials(
AuthScope.ANY,
new UsernamePasswordCredentials(username, password)
);
}
// 4. 配置超时时间(连接、Socket、请求排队)
builder.setRequestConfigCallback(requestConfigBuilder -> {
requestConfigBuilder.setConnectTimeout(connectTimeout);
requestConfigBuilder.setSocketTimeout(socketTimeout);
requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeout);
return requestConfigBuilder;
});
// 5. 配置连接池与认证
builder.setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.setMaxConnTotal(maxConnectNum); // 总连接数
httpClientBuilder.setMaxConnPerRoute(maxConnectPerRoute); // 单节点连接数
if (username != null && password != null) {
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
return httpClientBuilder;
});
// 6. 构建并返回客户端
RestHighLevelClient client = new RestHighLevelClient(builder);
log.info("ES 7.x HLRC客户端初始化完成,集群名称:{},服务器地址:{}", clusterName, hosts);
return client;
}
}
3.2 工具类(封装ES操作)
封装索引CRUD、文档CRUD、高亮查询等核心操作,避免重复代码。
java
package com.es.demo.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
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.support.master.AcknowledgedResponse;
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.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* ES 7.x HLRC工具类(封装核心操作)
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class Es7xHlrcUtil {
// 注入HLRC客户端(与配置类中Bean名称一致)
private final RestHighLevelClient es7xRestHighLevelClient;
// 常量定义
public static final String KEYWORD_SUFFIX = ".keyword"; // 精确匹配后缀(text类型字段用)
public static final TimeValue DEFAULT_TIMEOUT = TimeValue.timeValueSeconds(3); // 默认超时时间
/**
* 1. 创建索引(若已存在则返回false)
* @param indexName 索引名(需小写,无特殊字符)
* @param mapping DSL(可选,如指定字段类型、分词器,null则用默认映射)
*/
public boolean createIndex(String indexName, String mapping) throws IOException {
if (isIndexExist(indexName)) {
log.warn("索引[{}]已存在,无需重复创建", indexName);
return false;
}
CreateIndexRequest request = new CreateIndexRequest(indexName);
// 若传入mapping,则设置索引映射
if (StringUtils.isNotBlank(mapping)) {
request.mapping(mapping, XContentType.JSON);
}
CreateIndexResponse response = es7xRestHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
log.info("索引[{}]创建成功,响应状态:{}", indexName, response.isAcknowledged());
return response.isAcknowledged();
}
/**
* 2. 判断索引是否存在
*/
public boolean isIndexExist(String indexName) throws IOException {
GetIndexRequest request = new GetIndexRequest(indexName);
boolean exists = es7xRestHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
log.debug("索引[{}]存在状态:{}", indexName, exists);
return exists;
}
/**
* 3. 删除索引(若不存在则返回false)
*/
public boolean deleteIndex(String indexName) throws IOException {
if (!isIndexExist(indexName)) {
log.warn("索引[{}]不存在,无需删除", indexName);
return false;
}
DeleteIndexRequest request = new DeleteIndexRequest(indexName);
AcknowledgedResponse response = es7xRestHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
log.info("索引[{}]删除成功,响应状态:{}", indexName, response.isAcknowledged());
return response.isAcknowledged();
}
/**
* 4. 添加文档(自定义docId,不存在则新增,存在则覆盖)
* @param indexName 索引名
* @param docId 文档ID(null则让ES自动生成)
* @param data 文档数据(POJO或Map)
*/
public String addDoc(String indexName, String docId, Object data) throws IOException {
// 转换数据为JSON字符串
String jsonData = JSON.toJSONString(data);
IndexRequest request = new IndexRequest(indexName);
// 设置文档ID(null则自动生成)
if (StringUtils.isNotBlank(docId)) {
request.id(docId);
}
// 设置超时时间和数据
request.timeout(DEFAULT_TIMEOUT);
request.source(jsonData, XContentType.JSON);
IndexResponse response = es7xRestHighLevelClient.index(request, RequestOptions.DEFAULT);
log.info("文档添加成功:索引[{}],docId[{}],响应状态[{}]",
indexName, response.getId(), response.status().getStatus());
return response.getId(); // 返回实际的docId(自动生成或自定义)
}
/**
* 4. 重载:添加文档(自动生成UUID作为docId)
*/
public String addDoc(String indexName, Object data) throws IOException {
String autoDocId = UUID.randomUUID().toString().replace("-", "").toUpperCase();
return addDoc(indexName, autoDocId, data);
}
/**
* 5. 根据docId删除文档
*/
public boolean deleteDocByDocId(String indexName, String docId) throws IOException {
if (!isDocExist(indexName, docId)) {
log.warn("文档不存在:索引[{}],docId[{}]", indexName, docId);
return false;
}
DeleteRequest request = new DeleteRequest(indexName, docId);
request.timeout(DEFAULT_TIMEOUT);
DeleteResponse response = es7xRestHighLevelClient.delete(request, RequestOptions.DEFAULT);
log.info("文档删除成功:索引[{}],docId[{}],响应状态[{}]",
indexName, docId, response.status().getStatus());
return response.status().getStatus() == 200;
}
/**
* 6. 根据docId更新文档(部分更新,仅修改传入字段)
*/
public boolean updateDocByDocId(String indexName, String docId, Object updateData) throws IOException {
if (!isDocExist(indexName, docId)) {
log.warn("文档不存在:索引[{}],docId[{}],无法更新", indexName, docId);
return false;
}
// 转换更新数据为JSON字符串
String jsonData = JSON.toJSONString(updateData);
UpdateRequest request = new UpdateRequest(indexName, docId);
request.timeout(DEFAULT_TIMEOUT);
request.doc(jsonData, XContentType.JSON);
// 实时刷新(wait_for:等待刷新完成后返回,确保更新后可立即查询,性能略低)
request.setRefreshPolicy("wait_for");
UpdateResponse response = es7xRestHighLevelClient.update(request, RequestOptions.DEFAULT);
log.info("文档更新成功:索引[{}],docId[{}],响应状态[{}]",
indexName, docId, response.status().getStatus());
return response.status().getStatus() == 200;
}
/**
* 7. 根据docId查询文档
* @param fields 需要返回的字段(逗号分隔,如"name,age",null则返回所有字段)
*/
public Map<String, Object> getDocByDocId(String indexName, String docId, String fields) throws IOException {
if (!isDocExist(indexName, docId)) {
log.warn("文档不存在:索引[{}],docId[{}]", indexName, docId);
return null;
}
GetRequest request = new GetRequest(indexName, docId);
// 筛选返回字段
if (StringUtils.isNotBlank(fields)) {
request.fetchSourceContext(new FetchSourceContext(
true,
fields.split(","), // 需返回的字段
Strings.EMPTY_ARRAY // 需排除的字段(空数组表示不排除)
));
}
GetResponse response = es7xRestHighLevelClient.get(request, RequestOptions.DEFAULT);
Map<String, Object> docData = response.getSource();
// 补充docId到返回结果中(方便前端使用)
if (docData != null) {
docData.put("docId", response.getId());
}
return docData;
}
/**
* 8. 判断文档是否存在(仅判断存在性,不返回数据,性能更高)
*/
public boolean isDocExist(String indexName, String docId) throws IOException {
GetRequest request = new GetRequest(indexName, docId);
// 不获取文档内容,仅判断存在性
request.fetchSourceContext(new FetchSourceContext(false));
request.storedFields("_none_");
boolean exists = es7xRestHighLevelClient.exists(request, RequestOptions.DEFAULT);
log.debug("文档存在状态:索引[{}],docId[{}],存在[{}]", indexName, docId, exists);
return exists;
}
/**
* 9. 高亮查询(支持分页、排序、字段筛选)
* @param indexName 索引名
* @param searchSourceBuilder 查询条件(需外部构建,如匹配、范围查询)
* @param pageNum 页码(从1开始)
* @param pageSize 每页条数
* @param fields 返回字段(逗号分隔,null则返回所有)
* @param sortField 排序字段(null则不排序,text类型需加.keyword)
* @param highlightField 高亮字段(如"name")
*/
public List<Map<String, Object>> searchHighlight(String indexName,
SearchSourceBuilder searchSourceBuilder,
Integer pageNum,
Integer pageSize,
String fields,
String sortField,
String highlightField) throws IOException {
// 1. 配置分页(from = (页码-1)*每页条数)
int from = (pageNum - 1) * pageSize;
searchSourceBuilder.from(from).size(pageSize);
// 2. 配置排序(text类型字段需加.keyword才能精确排序)
if (StringUtils.isNotBlank(sortField)) {
if (sortField.contains(".")) {
searchSourceBuilder.sort(sortField, SortOrder.ASC);
} else {
searchSourceBuilder.sort(sortField + KEYWORD_SUFFIX, SortOrder.ASC);
}
}
// 3. 配置返回字段筛选
if (StringUtils.isNotBlank(fields)) {
searchSourceBuilder.fetchSource(new FetchSourceContext(
true,
fields.split(","),
Strings.EMPTY_ARRAY
));
}
// 4. 配置高亮(红色span标签)
if (StringUtils.isNotBlank(highlightField)) {
HighlightBuilder highlightBuilder = new HighlightBuilder();
HighlightBuilder.Field field = new HighlightBuilder.Field(highlightField)
.preTags("<span style='color:red'>")
.postTags("</span>")
.requireFieldMatch(false); // 允许高亮多个字段
highlightBuilder.field(field);
searchSourceBuilder.highlighter(highlightBuilder);
}
// 5. 执行查询
SearchRequest searchRequest = new SearchRequest(indexName);
searchRequest.source(searchSourceBuilder);
SearchResponse response = es7xRestHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
// 6. 解析查询结果(处理高亮字段)
List<Map<String, Object>> resultList = new ArrayList<>();
for (SearchHit hit : response.getHits().getHits()) {
Map<String, Object> docData = hit.getSourceAsMap();
// 补充docId
docData.put("docId", hit.getId());
// 替换高亮字段(将原始字段值替换为高亮后的内容)
if (StringUtils.isNotBlank(highlightField)) {
HighlightField highlight = hit.getHighlightFields().get(highlightField);
if (highlight != null && highlight.getFragments() != null) {
// 拼接多片段(如字段内容过长,ES会拆分为多个片段)
StringBuilder highlightValue = new StringBuilder();
for (Text fragment : highlight.getFragments()) {
highlightValue.append(fragment.string());
}
docData.put(highlightField, highlightValue.toString());
}
}
resultList.add(docData);
}
log.info("高亮查询完成:索引[{}],匹配总数[{}],分页[{}页/{}条]",
indexName, response.getHits().getTotalHits().value, pageNum, pageSize);
return resultList;
}
}
3.3 实体类(Employee7xHlrc)
与方式一类似,仅用于数据传输,无需ES注解(HLRC不依赖Spring Data注解)。
java
package com.es.demo.entity;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 员工实体(用于ES 7.x HLRC)
*/
@Data
public class Employee7xHlrc {
private String docId; // 文档ID(可选,HLRC可自动生成)
private String jobNo; // 工号
private String name; // 姓名
private String job; // 岗位
private Integer age; // 年龄
private BigDecimal salary; // 薪资
private Date jobDay; // 入职时间
private String remark; // 备注
}
3.4 Controller层(测试接口)
调用工具类实现业务接口,方便测试。
环境提示:
- 开发/测试环境:创建索引时可不传mapping参数,依赖ES动态映射快速验证接口功能;
- 生产环境:必须传入自定义mapping(如当前代码中指定字段类型和IK分词器的配置),精准控制字段属性,同时建议关闭动态映射并提前预创建索引。
java
package com.es.demo.controller;
import com.es.demo.entity.Employee7xHlrc;
import com.es.demo.util.Es7xHlrcUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Slf4j
@RestController
@RequestMapping("/api/hlrc7x/employee")
@RequiredArgsConstructor
public class Employee7xHlrcController {
private final Es7xHlrcUtil es7xHlrcUtil;
// 索引名(与实体类对应)
private static final String EMPLOYEE_INDEX = "employee_hlrc_7x";
/**
* 1. 创建员工索引(带自定义mapping,指定字段类型和分词器)
*/
@GetMapping("/index/create")
public String createIndex() {
// 自定义mapping(指定字段类型、IK分词器)
String mapping = "{\n" +
" \"properties\": {\n" +
" \"jobNo\": {\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"name\": {\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\",\n" +
" \"search_analyzer\": \"ik_smart\"\n" +
" },\n" +
" \"job\": {\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"age\": {\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"salary\": {\n" +
" \"type\": \"double\"\n" +
" },\n" +
" \"jobDay\": {\n" +
" \"type\": \"date\",\n" +
" \"format\": \"yyyy-MM-dd\"\n" +
" },\n" +
" \"remark\": {\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_smart\"\n" +
" }\n" +
" }\n" +
"}";
try {
boolean result = es7xHlrcUtil.createIndex(EMPLOYEE_INDEX, mapping);
return result ? "索引创建成功" : "索引已存在";
} catch (IOException e) {
log.error("创建索引失败", e);
return "索引创建失败:" + e.getMessage();
}
}
/**
* 2. 删除员工索引
*/
@GetMapping("/index/delete")
public String deleteIndex() {
try {
boolean result = es7xHlrcUtil.deleteIndex(EMPLOYEE_INDEX);
return result ? "索引删除成功" : "索引不存在";
} catch (IOException e) {
log.error("删除索引失败", e);
return "索引删除失败:" + e.getMessage();
}
}
/**
* 3. 添加员工文档(自动生成docId)
*/
@PostMapping("/save")
public String save(@RequestBody Employee7xHlrc employee) {
try {
String docId = es7xHlrcUtil.addDoc(EMPLOYEE_INDEX, employee);
return "员工添加成功,docId:" + docId;
} catch (IOException e) {
log.error("添加员工失败", e);
return "添加员工失败:" + e.getMessage();
}
}
/**
* 4. 根据docId查询员工
*/
@GetMapping("/get/{docId}")
public Map<String, Object> get(@PathVariable String docId) {
try {
// 仅返回name、job、salary、jobDay字段
return es7xHlrcUtil.getDocByDocId(EMPLOYEE_INDEX, docId, "name,job,salary,jobDay");
} catch (IOException e) {
log.error("查询员工失败(docId:{})", docId, e);
return null;
}
}
/**
* 5. 高亮查询员工(姓名模糊匹配)
*/
@GetMapping("/search-highlight")
public List<Map<String, Object>> searchHighlight(
@RequestParam String name,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
try {
// 构建查询条件:姓名模糊匹配(matchQuery支持分词)
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("name", name));
// 调用工具类高亮查询(按jobNo升序排序,高亮name字段)
return es7xHlrcUtil.searchHighlight(
EMPLOYEE_INDEX,
searchSourceBuilder,
pageNum,
pageSize,
"name,jobNo,job,age,salary", // 返回字段
"jobNo", // 排序字段(keyword类型,无需加后缀)
"name" // 高亮字段
);
} catch (IOException e) {
log.error("高亮查询员工失败(姓名关键词:{})", name, e);
return null;
}
}
/**
* 6. 测试示例:添加单个员工(手动传参)
*/
@GetMapping("/test/save")
public String testSave(
@RequestParam String jobNo,
@RequestParam String name,
@RequestParam String job,
@RequestParam Integer age,
@RequestParam BigDecimal salary,
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") Date jobDay,
@RequestParam(required = false) String remark) {
Employee7xHlrc employee = new Employee7xHlrc();
employee.setJobNo(jobNo);
employee.setName(name);
employee.setJob(job);
employee.setAge(age);
employee.setSalary(salary);
employee.setJobDay(jobDay);
employee.setRemark(remark);
try {
String docId = es7xHlrcUtil.addDoc(EMPLOYEE_INDEX, employee);
return "测试添加成功,docId:" + docId;
} catch (IOException e) {
log.error("测试添加员工失败", e);
return "测试添加失败:" + e.getMessage();
}
}
}
4. 测试步骤
- 启动ES 7.15.2服务器;
- 调用创建索引接口:
http://localhost:8082/api/hlrc7x/employee/index/create; - 调用测试添加接口:
http://localhost:8082/api/hlrc7x/employee/test/save?jobNo=2024002&name=李四&job=前端开发&age=26&salary=22000&jobDay=2023-03-20&remark=UI专家; - 调用高亮查询接口:
http://localhost:8082/api/hlrc7x/employee/search-highlight?name=李&pageNum=1&pageSize=10,验证高亮效果。