概要
本篇介绍一下multi_match的best_fields、most_fields和cross_fields三种语法的场景和简单示例。
最佳字段
bool查询采取"more-matches-is-better"匹配越多分越高的方式,所以每条match语句的评分结果会被加在一起,从而为每个文档提供最终的分数_score。能与两条语句同时匹配的文档会比只与一条语句匹配的文档得分要高,但有时这样也会带来一些与期望不符合的情况,我们举个例子:
我们以英文儿歌为案例背景,我们这样搜索:
GET /music/children/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"name": "brush mouth" }},
{
"match": {
"content": "you sunshine" }}
]
}
}
}
结果响应(有删减)
{
"hits": {
"total": 2,
"max_score": 1.7672573,
"hits": [
{
"_id": "4",
"_score": 1.7672573,
"_source": {
"name": "brush your teeth",
"content": "When you wake up in the morning it's a quarter to one, and you want to have a little fun You brush your teeth"
}
},
{
"_id": "3",
"_score": 0.7911257,
"_source": {
"name": "you are my sunshine",
"content": "you are my sunshine, my only sunshine, you make me happy, when skies are gray"
}
}
]
}
}
预期的结果是"you are my sunshine"要排在"brush you teeth"前面,实际结果却相反,为什么呢?
我们按照匹配的方式复原一下_score的评分过程:每个query的分数,乘以匹配的query的数量,除以总query的数量。
我们来看一下匹配情况:
文档4的name字段包含brush,content字段包含you,所以两个match都能得到评分。
文档3的name字段不匹配,但是content字段包含you和sunshine,命中一个match,只能得一项的分。
结果文档4的得分会高一些。
但我们仔细想一想,文档4虽然两个match都匹配了,但每个match只匹配了其中一个关键词,文档3只匹配了一个match,却是同时匹配了两个连续的关键词,按我们的预期,一个field上匹配了两个连续关键词的相关性应该高一些,简单的把多个match的得分加起来,虽然分高一些,但不是我们期望的首位。
我们探寻的是最佳字段匹配,某一个字段匹配到了尽可能多的关键词,让它排在前面;而不是更多的field匹配了关键词,就让它在前面。
我们使用dis_max语法查询,优先将最佳匹配的评分作为查询的评分结果返回,请求如下:
GET /music/children/_search
{
"query": {
"dis_max": {
"queries": [
{
"match": {
"name": "brush mouth" }},
{
"match": {
"content": "you sunshine" }}
]
}
}