场景
在使用 match
查询时,Elasticsearch 会根据文档与搜索词条的关联度计算得分(_score
),并按得分降序返回结果。如果需要人为控制文档的相关性算分,可以使用 Elasticsearch 的 function_score
查询。
用法
基本语法
function_score
查询中包含四部分内容:
- 原始查询条件:query部分,基于这个条件搜索文档,并且基于BM25算法给文档打分,原始算分(query score)
- 过滤条件:filter部分,符合该条件的文档才会重新算分
- 算分函数:符合filter条件的文档要根据这个函数做运算,得到的函数算分(function score),有四种函数
- weight:函数结果是常量
- field_value_factor:以文档中的某个字段值作为函数结果
- random_score:以随机数作为函数结果
- script_score:自定义算分函数算法
- 运算模式:算分函数的结果、原始查询的相关性算分,两者之间的运算方式,包括:
- multiply:相乘
- replace:用function score替换query score
- 其它,例如:sum、avg、max、min
运行流程
- 根据原始条件查询搜索文档,并且计算相关性算分,称为原始算分(query score)
- 根据过滤条件,过滤文档
- 符合过滤条件的文档,基于算分函数运算,得到函数算分(function score)
- 将原始算分(query score)和函数算分(function score)基于运算模式做运算,得到最终结果,作为相关性算分。
因此,其中的关键点是:
- 过滤条件:决定哪些文档的算分被修改
- 算分函数:决定函数算分的算法
- 运算模式:决定最终算分结果
案例
商城中商品有一个广告字段isAD,搜索时被推广的商品将排在最前。
实现以上需求,需要指定query类型为function_score,并在原始query的基础上,增加一个算分函数,人为过滤出包含推广字段的文档,并将得分附加上一个足够大的权重,查询语句如下所示:
1 | { |
对应到java代码如下:
1 | FilterFunctionBuilder[] functions = { |
代码注释说明
- 过滤条件:指定被推广的文档(
isAD: true
)。 - 算分函数:为符合条件的文档赋予权重 1000。
- 原始查询:基于商品名称
name
匹配 “手机”。 - 运算模式:将原始分数与函数值相加。
注意事项
- 只有在使用
match
查询时,才会根据得分排序,function_score
才会生效。 - 如果需要对所有文档应用算分函数,可以省略
filter
部分。 - 确保字段名称(如
isAD
)和查询条件(如term
查询)与实际索引中的字段一致。
__END__