好的,QueryBuilders.multiMatchQuery
是一个非常实用且强大的查询构建器。它的核心含义是:在多个字段中同时搜索一个查询关键词。
您可以将其理解为数据库中的 WHERE field1 LIKE '%keyword%' OR field2 LIKE '%keyword%' OR ...
,但远比这强大和高效。
核心含义与类比
MatchQuery
: 在一个指定的字段中搜索关键词。MultiMatchQuery
: 在多个指定的字段中搜索同一个关键词。
简单比喻: 假设您要在一堆简历中找人:
matchQuery("skill", "Java")
: 只查看“技能”这一栏,找会Java的人。multiMatchQuery("Java", "skill", "project_experience", "self_introduction")
: 同时查看“技能”、“项目经验”、“自我介绍”等多个栏目,找提到Java的人。这样找到的结果会更全面。
基本语法
import org.elasticsearch.index.query.QueryBuilders;
// 基本语法:QueryBuilders.multiMatchQuery(查询关键词, 字段名1, 字段名2, ...)
MultiMatchQueryBuilder query = QueryBuilders.multiMatchQuery("搜索词", "field1", "field2", "field3");
在 BoolQueryBuilder
中的典型用法
它经常作为 should
或 must
的一个子句,用于实现智能搜索。
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder()
.withQuery(
QueryBuilders.boolQuery()
// must: 硬性条件,如只要已发布的文章
.must(QueryBuilders.termQuery("status", "published"))
// should: 在多个字段中搜索用户输入的关键词,匹配的字段越多/越重要,得分越高
.should(
QueryBuilders.multiMatchQuery("Java 编程教程", "title", "content", "summary")
)
);
查询解释:查找所有已发布的文章,并在这些文章中,找出那些在标题、内容或摘要中提到了“Java”、“编程”、“教程”这些词的文档。在标题中匹配到的文档会比在内容中匹配到的得分更高(默认行为),因而排名更靠前。
核心特性:字段权重与评分
multiMatchQuery
最强大的地方在于你可以为不同的字段设置不同的权重(boost),从而影响搜索结果的相关性评分(_score
)。
语法:
使用 ^
符号后跟数字来指定权重。权重越高,在该字段匹配到的结果得分也越高。
// 语法: "字段名^权重"
MultiMatchQueryBuilder query = QueryBuilders.multiMatchQuery("搜索词")
.field("title", 10) // 在title字段中匹配到,得分乘以10(非常重要)
.field("summary", 2) // 在summary字段中匹配到,得分乘以2(比较重要)
.field("content"); // 在content字段中匹配到,得分乘以1(默认权重)
常用查询类型(type
)
通过 .type()
方法,你可以指定匹配的类型,以适应不同的搜索场景。
类型 | 含义 | 适用场景 |
---|---|---|
best_fields (默认值) |
“最佳匹配”。文档的得分由匹配度最高的那个字段决定。相当于 (field1:java OR field2:java) ,然后取分数最高的。 |
当用户期望搜索结果中至少有一个字段能很好地匹配查询词时。例如,搜索“Java”时,希望标题是“Java”的排在最前,而不是内容里提到很多次“Java”的。 |
most_fields |
“最多匹配”。会综合所有匹配字段的得分。 | 当查询词被分词后,你希望匹配到更多字段的文档排名更高。适用于类似“跨字段”的召回。 |
cross_fields |
“跨字段”。将所有字段视为一个“大字段”来进行匹配。它会处理类似 “停用词” 的问题。 | 当你的字段集共同构成一个整体信息时(如:firstName 和 lastName 合起来是人名)。它能让 "Will Smith" 的匹配效果比 "Smith" 出现在 firstName 而 "Will" 出现在 lastName 的文档更好。 |
phrase |
“短语匹配”。在每个字段中执行短语匹配(词序要一致)。 | 当需要精确匹配短语时,类似于 match_phrase 查询的多字段版本。 |
完整代码示例(结合 WebMtoPost
)
假设您的 WebMtoPost
文章类有以下字段,我们来实现一个智能搜索。
public class WebMtoPost {
private String title; // 标题
private String content; // 内容
private String summary; // 摘要
private String author; // 作者
private String status; // 状态
// ... 其他字段
}
场景:实现一个类似百度、谷歌的站内搜索引擎
import org.elasticsearch.index.query.QueryBuilders;
String userInput = "Java 编程 入门教程";
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder()
.withQuery(
QueryBuilders.boolQuery()
// 1. 硬性条件:只查询已发布的文章
.must(QueryBuilders.termQuery("status", "published"))
// 2. 核心搜索:在多个字段中搜索用户输入的关键词
.should(
QueryBuilders.multiMatchQuery(userInput)
// 设置字段权重:标题最重要,其次是摘要,最后是内容
.field("title", 10)
.field("summary", 3)
.field("content", 1)
// 使用最佳匹配模式:标题匹配度高的文章排在最前
.type(MultiMatchQueryBuilder.Type.BEST_FIELDS)
)
);
这个查询的搜索逻辑是:
- 过滤: 只找
status
为published
的文章。 - 搜索: 在
title
,summary
,content
这三个字段中搜索用户输入的“Java 编程 入门教程”。 - 排序:
- 如果一篇文章的标题高度相关(比如标题是《Java编程入门教程》),它会因为
title
字段的高权重(10)而获得非常高的分数,排在最前面。 - 如果标题不相关,但摘要里提到了这些词,也会被找到,但分数会低一些。
- 如果只在内容里提到,分数会更低,排在后面。
- 这正好符合用户对搜索引擎的预期:标题匹配的结果是最相关的。
- 如果一篇文章的标题高度相关(比如标题是《Java编程入门教程》),它会因为
总结
QueryBuilders.multiMatchQuery
是一个用于实现多字段智能搜索的核心工具。
- 核心功能:一个关键词,搜索多个字段。
- 核心优势:通过字段权重(boost) 和查询类型(type) 精细控制搜索结果的相关性排序。
- 典型应用:构建搜索引擎的“智能搜索”功能,是
BoolQueryBuilder
中should
子句的绝佳搭档。