ES翻译之Function Score Query

Function Score Query

原文链接

function_score允许你修改通过查询获取文档的分数,很有用处,score function是计算昂贵的,以及在过滤一系列文档上计算分数是高效的
想要使用function_score,使用者必须要定义一个查询和一个或者多个方法,方法是用来为每个文档通过查询计算分数。
function_score 可以通过仅仅一个方法如下:

curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
    "query": {
        "function_score": {
            "query": { "match_all": {} },
            "boost": "5",
            "random_score": {}, 
            "boost_mode":"multiply"
        }
    }
}
'

此外,多种方法可以进行组合使用,既然这样其中一个可以随意选择执行方法只要一个文档匹配给定字段的查询

curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
    "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
        }
    }
}
'

 


注意:过滤查询产生的分数不影响

如果没有过滤方法,这就相当于指定"match_all": {}
首先,每个文档通过定义的方法进行打分,参数"score_mode"指定了计算的分数是怎么组成的

  • multiply          分数相乘(默认)
  • sum               分数相加
  • avg                分数平均
  • first                第一个方法匹配过滤被应用
  • max               最大的分数
  • min                最小的分数

因为分数可以在不同的范围(例如:在0和1对于衰退函数 这里直接使用"field_value_factor")
以及因为有时候不同函数对分数的影响是可取的,不同函数生成的分数可以通过用户自定义的"weight"进行调整。
"weight"可以在"functions"数组中的每个方法进行定义(如下例子),乘以由各自函数计算的分数.
如果没有任何一个函数声明给定权重,"weight" 充当函数的功能简单的返回这个"weight".

假设"score_mode" 设置为"avg",通过加权的平均数组合成单独的分数。例如,
如果两个函数返回分数1和2,它们各自的权重分别是3和4,然后它们的分数将会
由下列的组合(1*3+2*4)/(3+4)而不是(1*3+2*4)/2.

新的分数将会严格限制不能超出指定的限制通过设置"max_boost"参数。默认的"max_boost"是FLT_MAX
新计算生成的分数是通过查询分数组成。参数"boost_mode"定义如下:

  • multiply      查询分数*函数分数相乘(默认)
  • replace      只使用函数的分数,忽略查询的分数
  • sum           查询分数和函数分数相加
  • avg           平均
  • max           取查询分数和函数分数中大的
  • min            取查询分数和函数分数中小的

默认情况下,修改分数并不改变文档的匹配,排除那些达不到指定分数的文档,可以通过设置"min_score"参数来
设置想要分数阈值。

注意:为了"min_score"工作,所有查询返回的文档必须被打分,并被一个又一个的过滤。

"function_score"查询提供了各种评分函数如下:

  • script_score
  • weight
  • random_score
  • field_value_factor
  • decay_functions:gauss,linear,exp

script_score
"script_score"函数允许您包装另一个查询,并可选地自定义它的得分,使用一个脚本表达式从doc中获得的其他数值字段值。
下面是简单的demo:

curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
    "query": {
        "function_score": {
            "query": {
                "match": { "message": "elasticsearch" }
            },
            "script_score" : {
                "script" : {
                  "source": "Math.log(2 + doc['likes'].value)"
                }
            }
        }
    }
}
'

 


除了不同的脚本字段值和表达式之外,"_score"脚本参数还可以用于根据包装查询检索分数。
脚本编译缓存起来用于更快速地执行。如果脚本有需要考虑的参数,最好是重用相同的脚本,
并为其提供参数。

curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
    "query": {
        "function_score": {
            "query": {
                "match": { "message": "elasticsearch" }
            },
            "script_score" : {
                "script" : {
                    "params": {
                        "a": 5,
                        "b": 1.2
                    },
                    "source": "params.a / Math.pow(params.b, doc['likes'].value)"
                }
            }
        }
    }
}
'

 

注意:这并不像"custom_score"查询,查询的分数和脚本评分的结果相乘。如果你想禁止它,设置"boost_mode":"replace".

Weight
"weight"分数允许你将分数乘以锁提供的权重。这有时是需要的,因为在特定查询上的boost值被规范化了,而对于这个分数函数
来说,它没有。数字的值是浮点类型。

"weight" : number

 

Random
"random_score"产生的分数是均匀分布在[0,1]之间。默认的,它使用了内部Luncene doc id来作为随机性的来源,这是分厂有效的,
但不幸的是不能复制,因为文档可能会被合并重新编号。
如果你希望分数是可复制的,那么就有可能提供一个seed和一个field。
最后的分数将根据这个seed计算出来,被考虑的文档的最小值和根据索引名称和碎片id计算的salt,以便具有相同值但存储在不同索引中的文档得到不同的分数.
注意,在相同的碎片中,在field中具有相同值的文档会得到相同的分数,所以通常需要使用一个对所有文档都有唯一值的field.
一个好的默认选择可能是使用"_seq_no"字段,它唯一的缺点是如果文档被更新,那么分数将会改变,因为更新操作也会更新"_seq_no"字段的值。


注意:在不设置field的情况下设置seed是可能的,但是这已经被弃用了,因为这需要在"_id"字段上加载fielddata,它会消耗大量的内存。

curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
    "query": {
        "function_score": {
            "random_score": {
                "seed": 10,
                "field": "_seq_no"
            }
        }
    }
}
'

 

Field Value factor
"field_value_factor"函数允许你从一个文档中使用一个字段来影响分数,和使用"script_score"函数类似,
但是,它避免了脚本的开销。如果在多值字段中使用,则只在计算中使用字段的第一个值。
举个例子,假设您有一个用数字"likes"字段索引的文档,并希望通过这个字段来影响文档的分数,这样做的示例看起来是这样的:

curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
    "query": {
        "function_score": {
            "field_value_factor": {
                "field": "likes",
                "factor": 1.2,
                "modifier": "sqrt",
                "missing": 1
            }
        }
    }
}
'

 

这将转化为以下的得分公式:

sqrt(1.2 * doc['likes'].value)

对于"field_value_factor"函数有许多选项:
  field    从文档中提取的字段。
  factor    使字段值与字段值相乘的可选因子,默认是1
  modifier    应用于字段值得修改器,可以是如下几种:: none, log, log1p, log2p, ln, ln1p, ln2p, square, sqrt, or reciprocal. 默认是 none.

Decay functions
衰减函数为一个文档提供一个函数,该函数根据给定来源的用户的数字字段值的距离而衰减。


未完待续...

转载于:https://www.cnblogs.com/atomicbomb/p/9105102.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值