Java ES搜索案例怎么条件查询

wen java案例 28

本文目录导读:

Java ES搜索案例怎么条件查询

  1. 使用 RestHighLevelClient(ES 7.x)
  2. 使用 Elasticsearch Java Client(ES 8.x)
  3. 关于条件查询的关键点总结
  4. 一个小建议

在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 和异步)。

如果需要更复杂的查询(如嵌套查询、聚合、高亮等),你可以告诉我具体要查什么,我可以给你更针对性的代码。

抱歉,评论功能暂时关闭!