🚀 玩转Elasticsearch 查询利器!QueryBuilders 核心方法全解析
以下整合了 Elasticsearch Java API 中 QueryBuilders 的常用方法,涵盖精确匹配、全文搜索、范围过滤、模糊查询等场景。每个方法均包含 用途说明、核心语法、示例代码 及 注意事项,帮助开发者快速掌握查询构建技巧。
一、布尔查询类
1.Elasticsearch QueryBuilders.boolQuery 方法详解
QueryBuilders.boolQuery 是 Elasticsearch Java API 中用于构建复杂查询逻辑的核心类,支持通过组合多个子查询(must、should、must_not、filter)实现灵活的条件筛选。以下从定义、常用方法、高级用法及注意事项展开说明,结合代码示例和最佳实践。
2.定义与用途
boolQuery 属于布尔查询,通过逻辑运算符组合多个子查询,适用于以下场景 1:
- 多条件组合:例如“同时满足 A 和 B”或“满足 A 或 B”。
- 过滤与评分分离:使用
filter子句过滤数据(不参与相关性评分),提升性能。 - 排除特定条件:通过
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)组合 filter 与 must
- 场景:先过滤数据,再执行评分查询。
- 示例:在 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("字段名", "精确值") - 示例:匹配
status为published的文档QueryBuilders.termQuery("status", "published") - 注意:
- 若字段为
text类型,需使用.keyword子字段(如title.keyword)。 - 适用于状态码、标签等离散值过滤。
- 若字段为
2. termsQuery - 多值精确匹配
- 用途:匹配字段值包含 多个精确值之一(类似 SQL 的
IN)。 - 语法:
QueryBuilders.termsQuery("字段名", "值1", "值2", ...) - 示例:筛选
category为tech或financeQueryBuilders.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) // 次要字段权重 - 示例:在
title和content中搜索 “搜索技术”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);
七、最佳实践与性能优化
-
优先使用过滤(Filter Context)
boolQuery.filter(rangeQuery("price").gte(100)) // 不计算评分,性能更高 -
避免通配符滥用
- 替代方案:使用
matchPhrasePrefixQuery实现自动补全。QueryBuilders.matchPhrasePrefixQuery("name", "张")
- 替代方案:使用
-
字段类型匹配
- 精确匹配用
keyword,全文搜索用text。
- 精确匹配用
-
索引设计优化
- 对高基数字段(如用户 ID)禁用分词:
{ "mappings": { "properties": { "user_id": { "type": "keyword" } } } }
- 对高基数字段(如用户 ID)禁用分词:
以上整合了
QueryBuilders的核心方法及实战技巧,覆盖 90% 的日常查询场景。更多高级用法(如脚本查询、地理位置查询)可参考 Elasticsearch 官方文档。


被折叠的 条评论
为什么被折叠?



