本文目录导读:

在Java中操作Elasticsearch进行条件查询,主要有两种方式:RestHighLevelClient(7.x及之前版本)和 Elasticsearch Java Client(8.x及以上版本,官方推荐)。
下面我分别给出两种方式的条件查询案例,涵盖 term, match, range, bool 组合查询等常见场景。
使用 RestHighLevelClient(ES 7.x)
依赖(Maven):
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.17.0</version>
</dependency>
单条件精确查询(term)
SearchRequest searchRequest = new SearchRequest("index_name");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 精确匹配字段 "status" 值为 "active"
sourceBuilder.query(QueryBuilders.termQuery("status", "active"));
searchRequest.source(sourceBuilder);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
模糊匹配查询(match)
sourceBuilder.query(QueryBuilders.matchQuery("title", "elasticsearch教程"));
范围查询(range)
// 查询价格在 10 到 100 之间的商品
sourceBuilder.query(QueryBuilders.rangeQuery("price")
.gte(10)
.lte(100));
多条件组合查询(bool)
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
// 必须满足:status = active
boolQuery.must(QueryBuilders.termQuery("status", "active"));
// 应该匹配:title 包含 "java"
boolQuery.should(QueryBuilders.matchQuery("title", "java"));
// 必须不匹配:category 不等于 "deleted"
boolQuery.mustNot(QueryBuilders.termQuery("category", "deleted"));
// 至少要满足一个 should 条件(默认不强制)
boolQuery.minimumShouldMatch(1);
sourceBuilder.query(boolQuery);
分页 + 排序 + 条件查询
sourceBuilder.query(QueryBuilders.matchQuery("name", "张三"));
sourceBuilder.from(0); // 从第0条开始
sourceBuilder.size(10); // 取10条
sourceBuilder.sort("age", SortOrder.DESC);
完整调用示例(伪代码)
try (RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")))) {
SearchRequest request = new SearchRequest("users");
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("active", true))
.must(QueryBuilders.rangeQuery("age").gte(18).lte(60))
);
request.source(builder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsString());
}
}
使用 Elasticsearch Java Client(ES 8.x)
这是官方最新的客户端,基于 co.elastic.clients:elasticsearch-java。
依赖:
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.12.0</version>
</dependency>
简单条件查询(term)
ElasticsearchClient client = ... // 初始化
SearchResponse<Map> response = client.search(s -> s
.index("products")
.query(q -> q
.term(t -> t
.field("status")
.value("active")
)
),
Map.class
);
Match 查询
response = client.search(s -> s
.index("articles")
.query(q -> q
.match(t -> t
.field("content")
.query("elasticsearch java")
)
),
Map.class
);
范围查询
response = client.search(s -> s
.index("orders")
.query(q -> q
.range(r -> r
.field("amount")
.gte(JsonData.of(100))
.lte(JsonData.of(500))
)
),
Map.class
);
Bool 组合查询
response = client.search(s -> s
.index("users")
.query(q -> q
.bool(b -> b
.must(m -> m.term(t -> t.field("active").value(true)))
.must(m -> m.range(r -> r.field("age").gte(JsonData.of(18))))
.should(sh -> sh.match(m -> m.field("tags").query("vip")))
.minimumShouldMatch("1")
)
),
Map.class
);
分页 + 排序
response = client.search(s -> s
.index("logs")
.query(q -> q.matchAll(m -> m))
.from(0)
.size(20)
.sort(so -> so.field(f -> f.field("timestamp").order(SortOrder.Desc)))
, Map.class
);
// 处理结果
for (Hit<Map> hit : response.hits().hits()) {
Map source = hit.source();
System.out.println(source);
}
关于条件查询的关键点总结
| 查询类型 | REST HL Client(7.x) | Java Client(8.x) | 说明 |
|---|---|---|---|
| 精确匹配 | termQuery("field","value") |
term(t -> t.field("f").value("v")) |
不分析,适合 keyword |
| 模糊匹配 | matchQuery("field","text") |
match(m -> m.field("f").query("text")) |
会分词 |
| 范围 | rangeQuery("f").gte(1).lte(10) |
range(r -> r.field("f").gte(...).lte(...)) |
可传数字或日期 |
| Bool | boolQuery().must(...).should(...) |
bool(b -> b.must(...).should(...)) |
最常用组合 |
| 分页 | from(0).size(10) |
.from(0).size(10) |
语法几乎一致 |
| 排序 | sort("field", SortOrder.ASC) |
.sort(so -> so.field(f -> f.field("f").order(...))) |
x 写法更函数式 |
一个小建议
- 如果你还在用 ES 7.x,建议用
RestHighLevelClient。 - 如果开始新项目或使用 ES 8.x,请直接使用
Elasticsearch Java Client(它性能更好、类型安全、支持 reactive 和异步)。
如果需要更复杂的查询(如嵌套查询、聚合、高亮等),你可以告诉我具体要查什么,我可以给你更针对性的代码。