ES8常用接口
ES 8.x 常用 Postman/ApiFox POST/GET 接口清单(HTTPS+Basic 认证)
前置统一配置
- 请求地址前缀:
https://11.53.102.203:9200 - Auth 选择 Basic Auth,填 elastic 账号密码
- 关闭 SSL 证书校验(内网自签 CA 必开,否则 PKIX 报错)
- 请求头固定:
Content-Type: application/json
一、索引管理接口(对应你业务表 T_las_eleasticsearch_index)
1. 判断索引是否存在(GET)
plaintext
GET /{indexName}
示例:
GET https://11.53.102.203:9200/todo-log- 返回 200 存在;404 不存在
代码对应:
indices.exists()
2. 创建索引(PUT)
plaintext
PUT /todo-log
{
"mappings": {
"properties": {
"id": {"type": "keyword"},
"title": {"type": "text", "analyzer": "ik_max_word"},
"createTime": {"type": "date", "format": "yyyy-MM-dd HH:mm:ss"}
}
},
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
}
}
3. 删除索引(谨慎使用,DELETE)
plaintext
DELETE /todo-log
4. 获取索引 Mapping 结构(GET)
plaintext
GET /todo-log/_mapping
5. 更新索引 Mapping 字段(PUT)
plaintext
PUT /todo-log/_mapping
{
"properties": {
"attachContent": {"type": "text", "analyzer": "ik_max_word"}
}
}
6. 获取索引配置 Settings
plaintext
GET /todo-log/_settings
二、文档 CRUD 接口(业务数据增删改查)
1. 全文检索查询(POST 最常用)
plaintext
POST /todo-log/_search
{
"from": 0,
"size": 10,
"query": {
"bool": {
"must": [
{"match": {"title": "项目待办"}},
{"term": {"userId.keyword": "admin"}}
],
"filter": [
{"range": {"createTime": {"gte": "2026-01-01"}}}
]
}
},
"sort": [{"createTime": {"order": "desc"}}]
}
2. 根据 ID 查询单条文档(GET)
plaintext
GET /todo-log/_doc/文档ID
3. 新增 / 覆盖文档(PUT)
plaintext
PUT /todo-log/_doc/1001
{
"id":"1001",
"title":"周报待办任务",
"userId":"admin",
"createTime":"2026-07-21 15:30:00"
}
4. 新增文档(自动生成 ID,POST)
plaintext
POST /todo-log/_doc
{
"title":"新流程待办"
}
5. 局部更新文档(POST _update)
plaintext
POST /todo-log/_doc/1001/_update
{
"doc": {
"title":"修改后的待办标题"
}
}
6. 根据 ID 删除文档(DELETE)
plaintext
DELETE /todo-log/_doc/1001
7. 条件批量删除(POST _delete_by_query)
plaintext
POST /todo-log/_delete_by_query
{
"query": {
"term": {"userId.keyword": "test"}
}
}
三、批量操作接口(同步大量业务数据)
批量插入 / 更新 / 删除 _bulk
plaintext
POST /todo-log/_bulk
{"index":{"_id":"1002"}}
{"title":"第一条批量数据"}
{"update":{"_id":"1001"}}
{"doc":{"title":"更新批量数据"}}
{"delete":{"_id":"999"}}
四、集群、健康、权限运维接口
- 集群健康状态
plaintext
GET /_cluster/health
- 查看所有索引列表
plaintext
GET /_cat/indices?v
- 节点信息
plaintext
GET /_nodes
- 账号权限校验(测试连通性)
plaintext
GET /_security/user/elastic/_has_privileges
{
"index": [{"names":["*"], "privileges":["read","write"]}]
}
五、附件 / 高亮、聚合常用扩展接口
- 检索高亮展示
json
POST /todo-log/_search
{
"query":{"match":{"title":"项目"}},
"highlight": {
"fields": {"title": {}}
}
}
- 聚合统计(分组计数)
json
POST /todo-log/_search
{
"size":0,
"aggs": {
"userGroup": {"terms": {"field":"userId.keyword"}}
}
}
六、你业务系统配套封装接口(后端 Controller)
你之前写的业务接口,不属于 ES 原生,是项目封装:
GET /lasEleasticsearchIndex/indexCheck/{indexName}校验索引是否存在- 新增 / 编辑索引配置:
POST /lasEleasticsearchIndex/save - 索引分页列表:
GET /lasEleasticsearchIndex/list - 索引字段保存:
POST /lasEleasticsearchIndexField/save - 根据索引 ID 查询字段列表:
GET /lasEleasticsearchIndexField/list/{indexId}
关键踩坑提示
- ES8 默认强制 HTTPS + Basic 认证,缺一不可;
- 自签证书必须关闭 Postman/ApiFox SSL 校验,否则报 PKIX 证书链错误;
_search必须 POST,GET 传请求体部分低版本 ES 不兼容;- keyword 字段用 term 精确匹配,text 字段用 match 分词检索;
- 生产禁止直接调用
DELETE /索引名,需后台做逻辑删除同步 ES。
---------------------------------------------------------
方案:案件 - 多文书 ES 全文检索(SpringBoot + MyBatis-Plus + Elasticsearch 8.x)
业务模型:1 条案件主表 → 关联多条文书附件(Word/PDF/PPT)
目标:支持输入关键词,同时检索【案件基础信息 + 所有文书附件文本内容】,命中案件返回。
一、两种架构选型对比
方案 A:宽表单索引(推荐,优先选用)
索引名:
一条案件对应一条 ES 文档;
案件基础字段平铺 + 数组存储多条文书文本。
✅ 优点:查询简单、分页友好、聚合方便;一次查询直接返回案件。
❌ 缺点:案件更新时,要重新合并所有文书内容写入 ES。
case_document_index
方案 B:父子文档(Join 类型)
- 父文档:案件信息
- 子文档:单条文书
✅ 优点:文书新增 / 修改可单独更新子文档,不用刷新整条案件❌ 缺点:DSL 复杂、分页性能一般,ES Join 性能有限,不推荐业务系统首选
结论:使用【方案 A 宽表模式】下文完整落地实现。
二、数据库表设计(MyBatis 实体基础)
1)案件主表 t_case_info
sql
CREATE TABLE t_case_info (
id NVARCHAR(36) PRIMARY KEY,
case_code NVARCHAR(100), -- 案件编号
case_name NVARCHAR(200), -- 案件名称
case_type NVARCHAR(50), -- 案件类型
litigant NVARCHAR(200), -- 当事人
create_time DATETIME,
creator_name NVARCHAR(50),
is_deleted BIT
);
2)案件文书附件表 t_case_file
sql
CREATE TABLE t_case_file (
id NVARCHAR(36) PRIMARY KEY,
case_id NVARCHAR(36), -- 关联案件ID
file_name NVARCHAR(200), -- 文件名称
file_suffix NVARCHAR(20), -- 后缀 word/pdf/ppt
file_path NVARCHAR(500), -- 文件存储路径
file_size BIGINT,
content_text NTEXT, -- 【可选】提前解析文本存入数据库
create_time DATETIME,
is_deleted BIT
);
三、依赖引入(pom.xml)
xml
<!-- Elasticsearch 8.x client -->
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- Tika 文档解析:提取word/pdf/ppt文本 -->
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>2.9.1</version>
</dependency>
四、ES 索引 Mapping 设计(宽表模型)
http
PUT /case_document_index
{
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"analysis": {
"analyzer": {
"ik_analyzer": {
"type": "custom",
"tokenizer": "ik_max_word"
}
}
}
},
"mappings": {
"properties": {
"caseId": {"type":"keyword"},
"caseCode": {"type":"keyword"},
"caseName": {"type":"text","analyzer":"ik_analyzer","fields":{"keyword":{"type":"keyword"}}},
"caseType": {"type":"keyword"},
"litigant": {"type":"text","analyzer":"ik_analyzer"},
"creatorName": {"type":"keyword"},
"createTime": {"type":"date","format":"yyyy-MM-dd HH:mm:ss"},
// 文书数组
"fileList": {
"type": "nested",
"properties": {
"fileId": {"type":"keyword"},
"fileName": {"type":"text","analyzer":"ik_analyzer"},
"fileSuffix": {"type":"keyword"},
"fileContent": {"type":"text","analyzer":"ik_analyzer"}
}
},
// 【关键】把所有文书内容合并成一个大文本,用于全局一键检索
"allFileContent": {"type":"text","analyzer":"ik_analyzer"}
}
}
}
重点说明:
nested fileList:保留每条文书独立信息,前端展示文件名;allFileContent:所有文书文本拼接汇总;用户输入关键词直接检索该字段,最简单高效;- 使用 IK 分词
ik_max_word支持中文全文检索。
五、ES 文档实体 Java
java
运行
import co.elastic.clients.elasticsearch._types.mapping.Type;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Data
public class CaseDocumentEs {
private String caseId;
private String caseCode;
private String caseName;
private String caseType;
private String litigant;
private String creatorName;
private LocalDateTime createTime;
// 文书嵌套数组
private List<CaseFileNested> fileList;
// 全部文书合并文本,用于统一检索
private String allFileContent;
@Data
public static class CaseFileNested {
private String fileId;
private String fileName;
private String fileSuffix;
private String fileContent;
}
}
六、核心能力 1:Apache Tika 解析文档文本
java
运行
import org.apache.tika.Tika;
import java.io.File;
import java.io.InputStream;
@Component
public class DocumentParseUtil {
private static final Tika tika = new Tika();
/**
* 提取word/pdf/ppt文本
*/
public String extractText(InputStream inputStream) throws Exception {
// 限制文本大小,防止超大文件
return tika.parseToString(inputStream);
}
}
支持格式:doc,docx,pdf,ppt,pptx;注意:超大文件建议异步解析,不要阻塞 http 请求。
七、同步逻辑(两种触发时机)
方式 1:新增 / 修改案件、新增文书 → 主动同步 ES(实时)
流程:
- 案件保存 / 上传文书成功
- 根据
caseId查询【案件信息 + 全部关联文书】 - 循环每个文书,调用 Tika 提取文本
- 组装
CaseDocumentEs,拼接allFileContent - ES upsert:存在则更新,不存在新增
方式 2:定时全量 / 增量同步(兜底补偿)
定时任务查询变更案件,重新构建文档写入 ES,防止消息丢失。
同步伪代码 Service
java
运行
@Service
public class CaseEsSyncService {
private final ElasticsearchClient esClient;
private final CaseInfoMapper caseInfoMapper;
private final CaseFileMapper caseFileMapper;
private final DocumentParseUtil parseUtil;
/**
* 根据案件ID同步ES
*/
public void syncCaseToEs(String caseId) {
// 1. 查询案件主信息
CaseInfo caseInfo = caseInfoMapper.selectById(caseId);
if (caseInfo == null || caseInfo.getIsDeleted()) {
// 案件已删除 → 删除ES文档
deleteEsDoc(caseId);
return;
}
// 2. 查询该案件所有文书
List<CaseFile> fileListDb = caseFileMapper.listByCaseId(caseId);
// 3. 组装ES实体,解析文本
CaseDocumentEs esDoc = new CaseDocumentEs();
esDoc.setCaseId(caseInfo.getId());
esDoc.setCaseCode(caseInfo.getCaseCode());
esDoc.setCaseName(caseInfo.getCaseName());
esDoc.setLitigant(caseInfo.getLitigant());
esDoc.setCreatorName(caseInfo.getCreatorName());
esDoc.setCreateTime(caseInfo.getCreateTime());
List<CaseDocumentEs.CaseFileNested> nestedList = new ArrayList<>();
StringBuilder allContentSb = new StringBuilder();
for (CaseFile file : fileListDb) {
CaseDocumentEs.CaseFileNested nested = new CaseDocumentEs.CaseFileNested();
nested.setFileId(file.getId());
nested.setFileName(file.getFileName());
nested.setFileSuffix(file.getFileSuffix());
String text;
if (StringUtils.hasText(file.getContentText())) {
// 数据库已预存解析文本,优先使用
text = file.getContentText();
} else {
// 读取文件流解析
try(InputStream is = getFileStream(file.getFilePath())){
text = parseUtil.extractText(is);
}catch (Exception e){
text = "";
}
}
nested.setFileContent(text);
nestedList.add(nested);
allContentSb.append(text).append(" ");
}
esDoc.setFileList(nestedList);
esDoc.setAllFileContent(allContentSb.toString());
// 4. upsert写入ES
upsertEs(esDoc);
}
}
八、全文检索 DSL 示例(用户查询入口)
需求:输入关键词,同时检索案件名称、当事人、所有文书内容
json
POST /case_document_index/_search
{
"from": 0,
"size": 10,
"query": {
"bool": {
"should": [
{
"match": {
"caseName": {
"query": "施工合同纠纷"
}
}
},
{
"match": {
"litigant": {
"query": "施工合同纠纷"
}
}
},
{
"match": {
"allFileContent": {
"query": "施工合同纠纷"
}
}
}
],
"minimum_should_match": 1
}
},
"sort": [
{"createTime":"desc"}
],
"highlight": {
"fields": {
"caseName": {},
"allFileContent": {}
}
}
}
九、常见问题 & 优化方案
1)文件解析慢、接口超时
✅ 方案:异步线程池解析文本,上传文件只落库,通过 MQ / 线程后台解析 + 同步 ES。
2)大 PDF 内容太大,ES 文档过大
✅ 限制提取文本长度;或者只解析前 N 页;
✅ 超大附件考虑只检索文件名,不提取全文。
3)新增单个文书,不想重新加载全部文书
两种选择:
- 依然使用宽表:每次新增文书触发一次全量查询刷新(中小体量项目完全够用)
- 切换父子文档模型(大数据量、文书频繁独立新增场景)
4)权限控制
ES 只做全文检索;数据权限必须在业务代码过滤:
查询 ES 拿到 caseId 列表 → 再 MyBatis 根据当前用户权限过滤案件 ID。
十、扩展:结合你前面【索引配置管理模块】
你之前开发的
可以把
6 个 / 多个检索字段(案件名称、当事人、文书名称、文书内容等)配置在明细表,
做到页面可视化配置检索字段,动态构建 ES 查询 DSL,不用硬编码字段。
T_las_eleasticsearch_index / T_las_eleasticsearch_index_field 配置表:
case_document_index 作为一条索引配置记录,
如果你需要,我可以继续输出:
- Controller 检索接口代码 + QueryDTO
- ElasticsearchClient 完整工具类(upsert、delete、search 封装)
- MQ 异步同步文书完整代码模板
- ------------------------------------------------------------------------------------------------------

浙公网安备 33010602011771号