🚀 Elasticsearch 双剑合璧:HTTP API 与 Java API 实战整合指南
一、HTTP API
定义与用途
Elasticsearch 的 HTTP API 是基于 RESTful 接口设计的核心交互方式,支持通过 URL 和 JSON 数据直接操作索引、文档、集群等资源。适用于快速调试、脚本调用和跨语言集成。
1. 索引管理
(1) 创建索引(指定分片与映射)
http">PUT /products
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"name": { "type": "text" },
"price": { "type": "integer" }
}
}
}
- 用途:初始化数据结构,定义字段类型和分片策略。
- 参数说明:
number_of_shards
:主分片数(不可修改)。mappings
:字段类型(如text
支持分词,keyword
精确匹配)。
product
:只是一个代表,是你要创建的索引的名称,索引可以理解为mysql中的一个表
settings
:配置
properties
:其内容就是你要写入到es的对象具体内容
(2) 删除索引
http">DELETE /products
- 风险提示:删除索引会清空所有数据,需谨慎操作。
2. 文档操作
(1) 新增文档(自动生成 ID)
http">POST /products/_doc
{
"name": "iPhone 14",
"price": 6999
}
- 响应示例:返回自动生成的
_id
(如_id: "x123"
)。
如上,请求体给出具体写到文档中的内容,文档可以理解为mysql中的一行数据记录
(2) 局部更新文档
http">POST /products/_update/x123
{
"doc": { "price": 6499 }
}
- 优势:仅更新指定字段,减少网络传输和索引重建开销。
3. 查询与聚合
(1) 条件查询(分页与排序)
http">GET /products/_search
{
"query": {
"match": { "name": "iPhone" }
},
"from": 0,
"size": 10,
"sort": [ { "price": "desc" } ]
}
- 性能注意:深度分页(
from > 10000
)需改用Search After
或Scroll API
。
from
和size
用于分页,from表示从第n个数据开始,size表示返回这个开始数据算起的m条文档数据
sort
表示按照什么字段排序,升序还是降序
(2) 聚合统计(平均值)
http">GET /products/_search
{
"aggs": {
"avg_price": { "avg": { "field": "price" } }
}
}
- 结果路径:
aggregations -> avg_price -> value
。
4. 批量操作
(1) 批量写入/删除
http">POST /_bulk
{ "index": { "_index": "products", "_id": "1" } }
{ "name": "iPad", "price": 3999 }
{ "delete": { "_index": "products", "_id": "2" } }
- 性能建议:单次批量操作不超过 10MB,避免超时。
二、Java API
定义与用途
Java API 是 Elasticsearch 官方提供的高层客户端库(RestHighLevelClient
),封装了 HTTP 请求的复杂性,支持强类型操作和异步处理。适用于后端服务开发。
1. RestHighLevelClient 常用方法
定义与用途
RestHighLevelClient
是 Java 客户端的入口类,通过调用其方法执行索引、文档、搜索等操作。需注意在 Elasticsearch 8.x 中已逐步迁移至新客户端 ElasticsearchClient
,但旧版仍广泛使用。
(1) 索引管理方法
方法签名 | 用途 | 对应 Request 类 |
---|---|---|
indices().create() | 创建索引 | CreateIndexRequest |
indices().delete() | 删除索引 | DeleteIndexRequest |
indices().exists() | 检查索引是否存在 | GetIndexRequest |
示例:创建索引
java">CreateIndexRequest request = new CreateIndexRequest("products")
.settings(Settings.builder().put("number_of_shards", 3))
.mapping(Map.of("properties", Map.of("name", Map.of("type", "text"))));
client.indices().create(request, RequestOptions.DEFAULT);
(2) 文档操作方法
方法签名 | 用途 | 对应 Request 类 |
---|---|---|
index() | 新增/全量替换文档 | IndexRequest |
update() | 局部更新文档 | UpdateRequest |
delete() | 删除文档 | DeleteRequest |
示例:局部更新文档
java">UpdateRequest request = new UpdateRequest("products", "x123")
.doc(Map.of("price", 6499));
client.update(request, RequestOptions.DEFAULT);
(3) 查询与聚合方法
方法签名 | 用途 | 对应 Request 类 |
---|---|---|
search() | 执行搜索 | SearchRequest |
scroll() | 滚动查询大数据量 | SearchScrollRequest |
示例:条件查询
java">SearchSourceBuilder source = new SearchSourceBuilder()
.query(QueryBuilders.matchQuery("name", "iPhone"))
.size(10);
SearchRequest request = new SearchRequest("products").source(source);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
2. Request 与 Builder 常用方法
定义与用途
每个操作对应一个 Request
类,通过 Builder 模式链式设置参数(如查询条件、分页、聚合等)。新版客户端(8.x)推荐使用流式语法(Lambda 表达式),旧版通过 XxxRequestBuilder
类构建。
(1) SearchRequest
与 SearchSourceBuilder
用途:构建复杂查询(分页、排序、聚合)。
- Request 方法
indices(String... indices)
:指定搜索的索引。source(SearchSourceBuilder source)
:绑定查询条件、分页、排序等。
- Builder 方法
query(QueryBuilder query)
:设置查询条件(如matchQuery
)。aggregation(AggregationBuilder aggregation)
:添加聚合逻辑(如avg
)。from(int).size(int)
:分页控制
对于
QueryBuilders
的详细介绍,看这篇文章
玩转Elasticsearch 查询利器!QueryBuilders 核心方法全解析-CSDN博客
核心方法:
java">SearchSourceBuilder source = new SearchSourceBuilder()
.query(QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("name", "iPhone"))
.filter(QueryBuilders.rangeQuery("price").gte(5000))
)
.aggregation(AggregationBuilders.avg("avg_price").field("price"))
.from(0).size(10);
SearchRequest request = new SearchRequest("products").source(source);
(2) BulkRequest
(批量操作)
用途:混合执行增删改操作。
- Request 方法
add(IndexRequest/UpdateRequest/DeleteRequest)
:混合添加增删改操作。
- Builder 方法
setRefreshPolicy(WriteRequest.RefreshPolicy)
:设置刷新策略(如IMMEDIATE
实时生效)。
示例:
java">BulkRequest bulkRequest = new BulkRequest();
bulkRequest.add(new IndexRequest("products").id("1").source("name", "iPad"));
bulkRequest.add(new DeleteRequest("products").id("2"));
client.bulk(bulkRequest, RequestOptions.DEFAULT);
(3) UpdateByQueryRequest
(按条件更新)
用途:批量更新符合查询条件的文档。
- Request 方法
setQuery(QueryBuilder query)
:筛选目标文档。setScript(Script script)
:定义更新逻辑。
示例:
java">UpdateByQueryRequest request = new UpdateByQueryRequest("products");
request.setQuery(QueryBuilders.termQuery("status", "pending"));
request.setScript(new Script("ctx._source.status = 'processed'"));
client.updateByQuery(request, RequestOptions.DEFAULT);
3. 整合示例:Request 与 Builder 协作
场景:构建复杂查询(分页 + 聚合 + 高亮)
java">// 1. 构建查询条件
SearchSourceBuilder source = new SearchSourceBuilder()
.query(QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("name", "iPhone"))
.filter(QueryBuilders.rangeQuery("price").gte(5000))
)
.aggregation(AggregationBuilders.avg("avg_price").field("price"))
.highlighter(new HighlightBuilder().field("name").preTags("<em>").postTags("</em>"))
.from(0).size(10);
// 2. 创建 Request 对象
SearchRequest request = new SearchRequest("products")
.source(source)
.indices("products", "sales"); // 跨索引查询
// 3. 执行查询
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
- 关键点:
SearchSourceBuilder
负责组装查询逻辑。SearchRequest
绑定查询条件并指定索引范围
三、最佳实践
-
性能优化
- 使用
BulkProcessor
自动分批次提交文档。 - 设置
setRefreshPolicy(WriteRequest.RefreshPolicy.NONE)
减少实时刷新开销。
- 使用
-
错误处理
java">try { client.index(request, RequestOptions.DEFAULT); } catch (ElasticsearchException e) { if (e.status() == RestStatus.CONFLICT) { // 处理版本冲突 } }
-
版本迁移
- Elasticsearch 8.x 推荐使用新客户端
ElasticsearchClient
,语法更简洁:java">client.search(s -> s .index("products") .query(q -> q.match(m -> m.field("name").query("iPhone"))) , Product.class);
- Elasticsearch 8.x 推荐使用新客户端