一、前言:当Java遇到Elasticsearch

在当代企业级应用中,Elasticsearch早已突破单纯的日志检索范畴,成为实时搜索的利器。作为Java开发者,掌握其核心查询能力就像厨师拿手好锅铲般重要。本文将手把手带你用Java Client实现两大硬核技能:精准过滤的查询设计,以及重点突出的高亮效果。


二、环境准备须知

技术栈明确声明:本文示例基于Elasticsearch 7.17 + Java High Level REST Client

  1. Maven依赖配置:
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.17.10</version>
</dependency>
  1. 初始化客户端最佳姿势:
RestHighLevelClient client = new RestHighLevelClient(
    RestClient.builder(
        new HttpHost("localhost", 9200, "http"),
        new HttpHost("127.0.0.1", 9200, "http")
    )
);

三、过滤查询的七十二变

3.1 基础过滤:就像筛网选豆子

场景:筛选2023年发布的手机数码类文章

SearchRequest request = new SearchRequest("articles");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

// 构建布尔查询(BoolQuery是瑞士军刀般的存在)
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
    .filter(QueryBuilders.termQuery("category.keyword", "手机数码")) // 精准过滤
    .filter(QueryBuilders.rangeQuery("publish_date")
        .gte("2023-01-01")
        .lte("2023-12-31"));

sourceBuilder.query(boolQuery);
request.source(sourceBuilder);

SearchResponse response = client.search(request, RequestOptions.DEFAULT);

3.2 组合过滤:多条件交响曲

要求:金融类文章,点赞过千的优先展示

BoolQueryBuilder complexFilter = QueryBuilders.boolQuery()
    .must(QueryBuilders.matchQuery("content", "量化投资")) // 必须包含关键词
    .filter(QueryBuilders.termQuery("category.keyword", "金融财经")) // 类别过滤
    .filter(QueryBuilders.rangeQuery("likes").gte(1000)) // 点赞数筛选
    .mustNot(QueryBuilders.existsQuery("is_deleted")); // 排除已删除文章

// 添加排序规则
sourceBuilder.sort(new FieldSortBuilder("likes").order(SortOrder.DESC));

四、高亮显示的艺术加工

4.1 基础高亮:让关键词闪亮登场

实现:搜索"人工智能"并突出显示

HighlightBuilder highlightBuilder = new HighlightBuilder()
    .field("content") // 指定高亮字段
    .preTags("<em class='highlight'>") // 开始标签
    .postTags("</em>") // 结束标签
    .numOfFragments(3); // 返回文本片段数量

sourceBuilder.highlighter(highlightBuilder);

// 执行查询后处理高亮结果
for (SearchHit hit : response.getHits()) {
    Text[] fragments = hit.getHighlightFields()
        .get("content")
        .getFragments();
    // 拼接高亮片段...
}

4.2 进阶高亮:多字段智能匹配

场景:跨标题和内容的高亮优化

HighlightBuilder multiHighlight = new HighlightBuilder()
    .field(new HighlightBuilder.Field("title")
        .preTags("<strong>")
        .postTags("</strong>"))
    .field("content")
    .requireFieldMatch(false) // 允许跨字段匹配
    .fragmentSize(150); // 每个片段长度

// 匹配策略配置(防止短文本截断问题)
multiHighlight.highlighterType("unified");

五、隐藏技能:聚合与过滤的化学反应

演示:统计不同类别文章的点赞区间分布

TermsAggregationBuilder categoryAgg = AggregationBuilders
    .terms("category_agg")
    .field("category.keyword");

RangeAggregationBuilder likesRange = AggregationBuilders
    .range("likes_range")
    .field("likes")
    .addRange(0, 100)
    .addRange(100, 1000)
    .addRange(1000, 10000);

sourceBuilder.aggregation(categoryAgg.subAggregation(likesRange));

六、场景分析与技术选择

6.1 典型应用场景

  • 电商平台:商品多维度筛选(价格区间+品牌+规格)
  • 内容社区:敏感词过滤与重点标红
  • 日志系统:错误级别过滤与关键字段突出

6.2 优势亮点

  1. 性能优势:Filter子句利用bitmap缓存,适合重复查询
  2. 组合灵活:多条件叠加如同乐高积木
  3. 用户体验:精准检索+焦点引导的完美结合

6.3 避坑指南

  • 高亮碎片不宜过多,影响响应速度
  • 注意keyword/text类型的过滤差异
  • 深度分页时优先search_after替代from/size

七、总结与展望

通过本文的实战演练,我们解锁了Elasticsearch在Java应用中的组合技。过滤查询如同精准的导航系统,而高亮显示则是信息地图的标记笔。随着elasticsearch-java客户端的持续演进(最新推荐使用Java API Client),开发者可以更优雅地构建智能搜索系统。下篇预告:聚合分析与自动补全的深度优化。