玩转Elasticsearch 查询利器!QueryBuilders 核心方法全解析

🚀 玩转Elasticsearch 查询利器!QueryBuilders 核心方法全解析

以下整合了 Elasticsearch Java API 中 QueryBuilders 的常用方法,涵盖精确匹配、全文搜索、范围过滤、模糊查询等场景。每个方法均包含 用途说明核心语法示例代码注意事项,帮助开发者快速掌握查询构建技巧。


一、布尔查询类


1.Elasticsearch QueryBuilders.boolQuery 方法详解

QueryBuilders.boolQuery 是 Elasticsearch Java API 中用于构建复杂查询逻辑的核心类,支持通过组合多个子查询(mustshouldmust_notfilter)实现灵活的条件筛选。以下从定义、常用方法、高级用法及注意事项展开说明,结合代码示例和最佳实践。


2.定义与用途

boolQuery 属于布尔查询,通过逻辑运算符组合多个子查询,适用于以下场景 1

  1. 多条件组合:例如“同时满足 A 和 B”或“满足 A 或 B”。
  2. 过滤与评分分离:使用 filter 子句过滤数据(不参与相关性评分),提升性能。
  3. 排除特定条件:通过 must_not 排除不符合条件的文档。

3.常用方法及示例
(1) must(必须匹配)
  • 用途:所有 must 子句必须匹配,相当于逻辑 AND
  • 示例:查询年龄等于 30 性别为男性的用户。
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
    .must(QueryBuilders.termQuery("age", 30))
    .must(QueryBuilders.termQuery("gender", "male"));
(2) should(至少匹配一个)
  • 用途:至少满足一个 should 子句,相当于逻辑 OR
  • 示例:查询标题包含 “Java” 内容包含 “编程” 的文章。
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
    .should(QueryBuilders.matchQuery("title", "Java"))
    .should(QueryBuilders.matchQuery("content", "编程"));
(3) must_not(禁止匹配)
  • 用途:排除符合子句条件的文档。
  • 示例:排除状态为 “已删除” 的文档。
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
    .mustNot(QueryBuilders.termQuery("status", "deleted"));
(4) filter(过滤条件)
  • 用途:过滤文档但不影响相关性评分,性能优于普通查询。
  • 示例:筛选价格在 100-500 元之间的商品。
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
    .filter(QueryBuilders.rangeQuery("price").gte(100).lte(500));

3.高级用法

(1)嵌套布尔查询
  • 场景:实现类似 SQL 的 (A AND B) OR (C AND D) 逻辑。
  • 示例:查询 (年龄>25 且性别=男) 或 (年龄<30 且性别=女) 的用户。
BoolQueryBuilder subQuery1 = QueryBuilders.boolQuery()
    .must(QueryBuilders.rangeQuery("age").gt(25))
    .must(QueryBuilders.termQuery("gender", "male"));

BoolQueryBuilder subQuery2 = QueryBuilders.boolQuery()
    .must(QueryBuilders.rangeQuery("age").lt(30))
    .must(QueryBuilders.termQuery("gender", "female"));

BoolQueryBuilder mainQuery = QueryBuilders.boolQuery()
    .should(subQuery1)
    .should(subQuery2);
(2)组合 filtermust
  • 场景:先过滤数据,再执行评分查询。
  • 示例:在 2023 年发布的文章中,搜索包含 “Elasticsearch” 的内容。
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
    .filter(QueryBuilders.rangeQuery("publish_time").gte("2023-01-01"))
    .must(QueryBuilders.matchQuery("content", "Elasticsearch"));
(3) 模糊查询与通配符
  • 场景:支持通配符 *?,需注意性能损耗 4
  • 示例:模糊查询姓名包含 “王” 的用户(不区分大小写)。
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
    .must(QueryBuilders.wildcardQuery("name.keyword", "*王*").caseInsensitive(true));

二、精确匹配类

1. termQuery - 精确值匹配
  • 用途:对 keyword 类型字段进行 完全匹配,不进行分词。
  • 语法
    QueryBuilders.termQuery("字段名", "精确值")
    
  • 示例:匹配 statuspublished 的文档
    QueryBuilders.termQuery("status", "published")
    
  • 注意
    • 若字段为 text 类型,需使用 .keyword 子字段(如 title.keyword)。
    • 适用于状态码、标签等离散值过滤。
2. termsQuery - 多值精确匹配
  • 用途:匹配字段值包含 多个精确值之一(类似 SQL 的 IN)。
  • 语法
    QueryBuilders.termsQuery("字段名", "值1", "值2", ...)
    
  • 示例:筛选 categorytechfinance
    QueryBuilders.termsQuery("category", "tech", "finance")
    
  • 扩展:支持动态从其他文档获取条件值(termsLookupQuery)。

三、全文搜索类

1. matchQuery - 分词匹配

  • 用途:对 text 类型字段进行 分词后匹配,支持模糊搜索。
  • 语法
    QueryBuilders.matchQuery("字段名", "关键词")
      .operator(Operator.AND)     // 要求所有分词匹配(默认 OR)
      .minimumShouldMatch("75%") // 至少匹配 75% 的分词
    
  • 示例:搜索标题包含 “Elasticsearch指南” 的文档
    QueryBuilders.matchQuery("title", "Elasticsearch指南")
    
  • 注意
    • 分词结果受分词器影响(如中文需配置 IK 分词器)。
    • 设置 operator(Operator.AND) 可严格匹配所有分词。

2. multiMatchQuery - 跨字段搜索

  • 用途:在 多个字段 上执行同一关键词的全文搜索。
  • 语法
    QueryBuilders.multiMatchQuery("关键词", "字段1", "字段2")
      .type(MultiMatchQueryBuilder.Type.BEST_FIELDS) // 评分策略
      .tieBreaker(0.3) // 次要字段权重
    
  • 示例:在 titlecontent 中搜索 “搜索技术”
    QueryBuilders.multiMatchQuery("搜索技术", "title", "content")
    
  • 优化:通过 ^ 设置字段权重(如 "title^3" 表示标题权重为 3)。

四、范围过滤类

1. rangeQuery - 区间过滤

  • 用途:对数值、日期等字段进行 区间过滤
  • 语法
    QueryBuilders.rangeQuery("字段名")
      .gte(100)    // >= 100
      .lt(1000)   // < 1000
      .format("yyyy-MM-dd")  // 日期格式
    
  • 示例:筛选价格在 100-1000 之间的商品
    QueryBuilders.rangeQuery("price").gte(100).lte(1000)
    
  • 扩展方法
    • gt():大于
    • lt():小于
    • includeUpper(false):排除上限值。

五、模糊与通配符类

1. wildcardQuery - 通配符匹配

  • 用途:使用 *(任意字符)和 ?(单个字符)进行 模式匹配
  • 语法
    QueryBuilders.wildcardQuery("字段名", "通配符模式")
    
  • 示例:匹配以 “张” 开头的姓名
    QueryBuilders.wildcardQuery("name.keyword", "张*")
    
  • 注意
    • 避免前缀通配符(如 *张),可能导致全索引扫描。
    • 优先对 keyword 类型字段使用。

2. fuzzyQuery - 模糊匹配

  • 用途:基于 编辑距离(Levenshtein 算法)实现容错匹配。
  • 语法
    QueryBuilders.fuzzyQuery("字段名", "目标值")
      .fuzziness(Fuzziness.AUTO)  // 自动计算允许的编辑距离
      .prefixLength(2)            // 前 2 个字符必须精确匹配
    
  • 示例:容错匹配 “elastiksearch”
    QueryBuilders.fuzzyQuery("content", "elastiksearch").fuzziness(Fuzziness.ONE)
    
  • 场景:拼写纠错、模糊搜索。

六、存在性与嵌套对象

1. existsQuery - 存在性检查

  • 用途:检查字段是否存在(非 null 或空值)。
  • 语法
    QueryBuilders.existsQuery("字段名")
    
  • 示例:筛选存在 author 字段的文档
    QueryBuilders.existsQuery("author")
    

2. nestedQuery - 嵌套对象查询

  • 用途:查询嵌套对象(字段类型需为 nested)。
  • 语法
    QueryBuilders.nestedQuery("嵌套路径", 
        QueryBuilders.termQuery("嵌套字段", "值"), 
        ScoreMode.Avg)  // 评分策略
    
  • 示例:查询评论中用户为 “kimchy” 的文档
    QueryBuilders.nestedQuery("comments", 
        QueryBuilders.termQuery("comments.user", "kimchy"), 
        ScoreMode.Avg)
    

六、整合示例:复杂查询场景

场景:搜索标题包含 “Elasticsearch” 价格在 100-1000 元 分类为 “技术” 的商品

// 1. 构建布尔查询
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
    .must(QueryBuilders.matchQuery("title", "Elasticsearch"))  // 必须匹配标题
    .filter(QueryBuilders.rangeQuery("price").gte(100).lte(1000)) // 过滤价格
    .should(QueryBuilders.termQuery("category", "技术"))          // 可选匹配分类
    .minimumShouldMatch(1);  // 至少满足一个 should 条件

// 2. 分页与排序
SearchSourceBuilder source = new SearchSourceBuilder()
    .query(boolQuery)
    .from(0).size(10)
    .sort("price", SortOrder.DESC);

// 3. 执行查询
SearchRequest request = new SearchRequest("products").source(source);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);

七、最佳实践与性能优化

  1. 优先使用过滤(Filter Context)

    boolQuery.filter(rangeQuery("price").gte(100)) // 不计算评分,性能更高
    
  2. 避免通配符滥用

    • 替代方案:使用 matchPhrasePrefixQuery 实现自动补全。
      QueryBuilders.matchPhrasePrefixQuery("name", "张")
      
  3. 字段类型匹配

    • 精确匹配用 keyword,全文搜索用 text
  4. 索引设计优化

    • 对高基数字段(如用户 ID)禁用分词:
      {
        "mappings": {
          "properties": {
            "user_id": { "type": "keyword" }
          }
        }
      }
      

以上整合了 QueryBuilders 的核心方法及实战技巧,覆盖 90% 的日常查询场景。更多高级用法(如脚本查询、地理位置查询)可参考 Elasticsearch 官方文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值