搜索服务的职责是把稳定的业务 API 转换成 Elasticsearch 查询,并隔离客户端版本、DSL 和索引结构。本文先运行一个内存实现,接口合同稳定后再替换为官方 Java Client。
Table of contents
运行完整 API
进入搜索架构实验室下载,执行:
mvn spring-boot:run
另开终端查询:
curl 'http://localhost:8080/products/search?q=java&category=book&size=10'
入口在ProductSearchController.java下载。Controller 只接收 q、category 和受限 size,不会暴露任意 DSL。
@GetMapping("/search")
public MiniSearchEngine.Page search(
@RequestParam(name = "q") String q,
@RequestParam(name = "category", required = false) String category,
@RequestParam(name = "size", defaultValue = "10") int size) {
return engine.search(q, category, null, size);
}
替换成真实客户端
生产项目使用官方 Elasticsearch Java Client。客户端 9.x 要求 Java 17+,并与服务器主版本对齐;连接器应作为单例 Bean 复用连接池。
Service 层负责构造 bool 查询、source 字段选择、超时与结果映射。不要把命中结果直接反序列化为数据库实体,搜索文档应有独立 DTO 和 schemaVersion。
错误必须可处理
参数错误返回 400 与 ProblemDetail;连接超时返回 503 并标记可重试;索引或字段不存在通常表示部署/映射错误,应告警而不是返回空列表。响应记录 took、是否超时和分片失败,但不要泄露节点地址或查询中的敏感信息。
curl 'http://localhost:8080/products/search?q=java&size=101'
# HTTP 400,detail: "size 必须在 1..100"
读取搜索通常可以做短重试,但必须受总截止时间约束。索引写入采用稳定文档 ID,并按错误项处理 Bulk 部分失败。
下一步
继续阅读09-08 深分页、游标与 Search After,为结果列表设计稳定游标。