ES 搜索20 (function_score 和 field_value_factor 自定义评分)

自定义评分

设想有个网站供用户发布博客并且可以让他们为自己喜欢的博客点赞, 我们希望将更受欢迎的博客放在搜索结果列表中相对较上的位置,同时全文搜索的评分仍然作为相关度的主要排序依据,可以简单的通过存储每个博客的点赞数来实现它:

在搜索时,可以将 function_score 查询与 field_value_factor 结合使用, 即将点赞数与全文相关度评分结合:

GET /blogposts/post/_search
{
  "query": {
    "function_score": {           1
      "query": {                  2
        "multi_match": {
          "query":    "popularity",
          "fields": [ "title", "content" ]
        }
      },
      "field_value_factor": {        3
        "field": "votes"             4
      }
    }
  }
}

1

function_score 查询将主查询和函数包括在内。

2

主查询优先执行。

3

field_value_factor 函数会被应用到每个与主 query 匹配的文档。

4

每个文档的 votes 字段都 必须 有值供 function_score 计算。如果 没有 文档的 votes 字段有值,那么就 必须 使用 missing 属性 提供的默认值来进行评分计算。所有查询字段都会和 field 所指定的字段进行评分的计算

 

modifier

一种融入受欢迎度更好方式是用 modifier 平滑 votes 的值。 换句话说,我们希望最开始的一些赞更重要,但是其重要性会随着数字的增加而降低。 0 个赞与 1 个赞的区别应该比 10 个赞与 11 个赞的区别大很多。

GET /blogposts/post/_search
{
  "query": {
    "function_score": {
      "query": {
        "multi_match": {
          "query":    "popularity",
          "fields": [ "title", "content" ]
        }
      },
      "field_value_factor": {
        "field":    "votes",
        "modifier": "log1p"            1
      }
    }
  }
}

1

modifier 为 log1p 。

修饰语 modifier 的值可以为: none (默认状态)、 log 、 log1p 、 log2p 、 ln 、 ln1p 、 ln2p、 square 、 sqrt 以及 reciprocal 。想要了解更多信息请参照: field_value_factor 文档.(不做详细介绍)

factor

可以通过将 votes 字段与 factor 的积来调节受欢迎程度效果的高低:

GET /blogposts/post/_search
{
  "query": {
    "function_score": {
      "query": {
        "multi_match": {
          "query":    "popularity",
          "fields": [ "title", "content" ]
        }
      },
      "field_value_factor": {
        "field":    "votes",
        "modifier": "log1p",
        "factor":   2 
      }
    }
  }
}

factor 值大于 1 会提升效果, factor 值小于 1 会降低效果

boost_mode

或许将全文评分与 field_value_factor 函数值乘积的效果仍然可能太大, 我们可以通过参数 boost_mode 来控制函数与查询评分 _score 合并后的结果,参数接受的值为:

multiply

评分 _score 与函数值的积(默认)

sum

评分 _score 与函数值的和

min

评分 _score 与函数值间的较小值

max

评分 _score 与函数值间的较大值

replace

函数值替代评分 _score

与使用乘积的方式相比,使用评分 _score 与函数值求和的方式可以弱化最终效果,特别是使用一个较小 factor 因子时:

GET /blogposts/post/_search
{
  "query": {
    "function_score": {
      "query": {
        "multi_match": {
          "query":    "popularity",
          "fields": [ "title", "content" ]
        }
      },
      "field_value_factor": {
        "field":    "votes",
        "modifier": "log1p",
        "factor":   0.1
      },
      "boost_mode": "sum"         1
    }
  }
}

1

将函数计算结果值累加到评分 _score 。

 

max_boost

最后,可以使用 max_boost 参数限制一个函数的最大效果:

GET /blogposts/post/_search
{
  "query": {
    "function_score": {
      "query": {
        "multi_match": {
          "query":    "popularity",
          "fields": [ "title", "content" ]
        }
      },
      "field_value_factor": {
        "field":    "votes",
        "modifier": "log1p",
        "factor":   0.1
      },
      "boost_mode": "sum",
      "max_boost":  1.5 
    }
  }
}

 

无论 field_value_factor 函数的结果如何,最终结果都不会大于 1.5 。

 

max_boost 只对函数的结果进行限制,不会对最终评分 _score 产生直接影响。

上一篇:abp.io和vue项目部署在iis同一站点,spa


下一篇:python构造程序逻辑