14-DSL查询语法-复合查询-算分函数查询

 复合(compound)查询:复合查询可以将其它简单查询组合起来,实现更复杂的搜索逻辑。常见的有两种:

(1)fuction score:算分函数查询,可以控制文档相关性算分,控制文档排名

(2)bool query:布尔查询,利用逻辑关系组合多个其它的查询,实现复杂搜索

 相关性算分

当我们利用match查询时,文档结果会根据与搜索词条的关联度打分(_score),返回结果时按照分值降序排列。elasticsearch会根据词条和文档的相关度做打分,算法由两种:

(1)TF-IDF算法

(2)BM25算法,elasticsearch5.1版本后采用的算法

算分函数查询

以百度为例,你搜索的结果中,并不是相关度越高排名越靠前,而是谁掏的钱多排名就越靠前。如图:

 

要想人为控制相关性算分,就需要利用elasticsearch中的function score 查询了。

 语法说明

function score 查询中包含四部分内容:

(1)原始查询条件:query部分,基于这个条件搜索文档,并且基于BM25算法给文档打分,原始算分(query score)

(2)过滤条件:filter部分,符合该条件的文档才会重新算分

(3)算分函数:符合filter条件的文档要根据这个函数做运算,得到的函数算分(function score),有四种函数

weight:函数结果是常量

field_value_factor:以文档中的某个字段值作为函数结果

random_score:以随机数作为函数结果

script_score:自定义算分函数算法

(4)运算模式:算分函数的结果、原始查询的相关性算分,两者之间的运算方式,包括:

multiply:相乘

replace:用function score替换query score

其它,例如:sum、avg、max、min

function score的运行流程:

1)根据原始条件查询搜索文档,并且计算相关性算分,称为原始算分(query score)

2)根据过滤条件,过滤文档

3)符合过滤条件的文档,基于算分函数运算,得到函数算分(function score)

4)将原始算分(query score)和函数算分(function score)基于运算模式做运算,得到最终结果,作为相关性算分。

关键点:

(1)过滤条件:决定哪些文档的算分被修改

(2)算分函数:决定函数算分的算法

(3)运算模式:决定最终算分结果

示例

需求:给“君悦”这个品牌的酒店排名靠前一些

翻译一下这个需求,转换为之前说的四个要点:

  1. 原始条件:不确定,可以任意变化
  2. 过滤条件:brand = "君悦"
  3. 算分函数:可以简单粗暴,直接给固定的算分结果,weight
  4. 运算模式:比如求和

因此最终的DSL语句如下:

 1 #算分函数查询
 2 
 3 #未添加算分函数时
 4 GET /hotel/_search 
 5 {
 6   "query":{
 7     "function_score":{
 8       "query":{
 9         "match":{
10           "all": "外滩"
11         }
12       }
13     }
14   }
15 }
16 
17 #添加算分函数后
18 GET /hotel/_search 
19 {
20   "query":{
21     "function_score":{
22       "query":{
23         "match":{
24           "all": "外滩"
25         }
26       },
27       "functions": [
28         {
29           "filter": {
30             "term": {
31               "brand": "君悦"
32             }
33           }, 
34           "weight": 10
35         }
36       ],
37       "boost_mode": "sum"
38     }
39   }
40 }
View Code

测试,在未添加算分函数时,得分如下:

添加了算分函数后,得分就提升了:

 

posted @ 2023-05-22 11:42  JustJavaIt  阅读(87)  评论(0编辑  收藏  举报