欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

elasticsearch的functionQuery

程序员文章站 2022-03-31 15:27:50
...

之前使用solr的时候,也接触过functionQuery,他就是用来对一个doc计算得分的,只改变排序,不改变match。es的functionQuery是第一次接触,看了看公司的代码,然后百度了一下,最后再看了下ES的官方文档,算是把ES的functionQuery给弄清楚了,再次记录下来。

 

ES的functionQuery需要两个主要变量,一个是query,用来计算候选集,也就是所有的doc的来源,一个是functionQuery,代码如下:

GET /_search
{
  "query": {
    "function_score": {
      "query": { "match_all": {} },
      "boost": "5", 
      "functions": [
        {
          "filter": { "match": { "test": "bar" } },
          "random_score": {}, 
          "weight": 23
        },
        {
          "filter": { "match": { "test": "cat" } },
          "weight": 42
        }
      ],
      "max_boost": 42,
      "score_mode": "max",
      "boost_mode": "multiply",
      "min_score": 42
    }
  }
}
 里面的query和functions是最重要的,query决定了候选集,也就是都是哪些doc要背functions里面的function计算得分。functions里面的都是函数,用来对query中命中的doc计算得分,所以functions中的函数只影响排序,不影响match的结果。对于每一个function,还有一个filter,这个表示只有被这个filter接受的doc才可以参与得分,如果没有写filter则表示match_all,注意filter的得分不考虑,不参与函数的得分,里面的weight,表示最终这个function的得分要乘以这个weight。

再说一下function_query中的其他参数:

  1. boost:这个是对于整个function_query的boost,就是lucene的boostedquery中的boost,不是我们要讨论的问题。
  2. max_boost:这个的意思是对于functions中的函数的最终得分,取一个上限,不能超过这个值。
  3. score_mode:这个表示的是多个function的值如何处理,可能是相加、相乘、取平均数、取最大值、最小值等。
  4. boost_mode:这个表示的是在算最终的得分的时候,怎么处理函数的得分和query的得分(也就是上面的query的得分),可以是相乘、相加、取代、取平均值等,如果不写,默认是相乘。
  5. min_score:这个的意思是如果一个doc的最终得分低于min_score,则不要这个doc,也就是规定了得分的下限。
 
函数,除了上面的functions中定义的query类型的,有好几个现成的的,下面的这几个最常用的。
1、script_score
    用脚本来实现的得分的逻辑,如下:
GET /_search
{
  "query": {
    "function_score": {
      "query": {
        "match": { "message": "elasticsearch" }
      },
      "script_score": {
        "script": {
          "params": {// 需要传入一个参数map,这个map用params表示。
            "a": 5,
            "b": 1.2
          },
          "source": "params.a / Math.pow(params.b, doc['my-int'].value)"// params就是上面的map,doc表示当前计算的doc,my-int表示一个字段,
        }
      }
    }
  }
}
 再ES中,可以将脚本保留在ES上,然后取一个id,以后的使用就可以直接根据id来从ES集群中获得这个脚本而不用每次都传到ES了。
2、Random, 随机数
GET /_search
{
  "query": {
    "function_score": {
      "random_score": {
        "seed": 10,
        "field": "_seq_no"
      }
    }
  }
}
 默认情况下,是按照lucene的内部id来计算随机值的,这样也是最有效率的,但是这个值会变,所以如果能接受同一个doc的函数值会变,就可以使用这个,否则必须要提供一个seed和field,用来计算随机值,另外还会使用这个doc所在的分片参与最终得分的计算,所以如果field中值是一样的,如果不同分片中的,可能会有不同的值,同一个分片中的有相同的值。
 3、filed_value_factor
这个是使用字段的值来计算得分的,如下:
GET /_search
{
  "query": {
    "function_score": {
      "field_value_factor": {
        "field": "my-int",// 字段
        "factor": 1.2,
        "modifier": "sqrt",
        "missing": 1
      }
    }
  }
}
 上面每个属性的意思解释如下:
field:字段
factor:将字段的分值乘以这个值
modifier:这个是对factor*field.value的值再做计算的,他有好多函数比如:none(没有任何操作),log(对数函数),log1p(加一后取对数),log2p(加2后取对数),ln, ln1p,ln2p,sqrt等。