function_score 之script_score

function_score  配合 script_score 是排序的终极方案

例子:

curl -XGET ‘http://localhost:9200/alias-product/product/_search?pretty&explain‘ -d ‘{

"size" : 0,

"query" : {

"function_score" : {

"query" : {

"filtered" : {

"filter" : {

"bool" : {

"must" : {

"match" : {

"_all" : {

"query" : "关键字",

"type" : "boolean",

"operator" : "AND"

}

}

}

}

}

}

},

"functions" : [ {

"script_score" : {

"params": {

"field": "company_name",

"term": "关键字"

},

"script" : "_index[field][term].df()"

}

} ,

{

"filter" : {

"match" : {

"company_name" : {

"query" : "关键字",

"type" : "boolean",

"operator" : "AND"

}

}

},

"weight" : 2

}

],

"score_mode" : "sum"

}

},

"aggregations" : {

"agg" : {

"terms" : {

"field" : "member_id",

"size" : 0,

"order" : {

"top_hit" : "desc"

}

},

"aggregations" : {

"top_hit" : {

"max" : {

"script" : {

"inline" : "_score"

}

}

}

}

}

}

}‘

需要配置:

script.engine.groovy.inline.search: on

script.inline: on

script.indexed: on

script_score可以让你更加灵活的操作ES的打分。例如

"script_score" : {

"params": {

"field": "company_name",

"terms": ["关键字"]

},

"script" : "score = 0.0; queryLength = 0.0; docLength = 0.0; for (word in terms) { tf = _index[field][word].tf(); score = score + tf * 1.0; queryLength = queryLength + 1.0; docLength = docLength + pow(tf, 2.0); }; return (float)score /(sqrt(docLength) * sqrt(queryLength)); "

}

这里需要注意的是 company_name 这个字段 不允许分词,否则这个近似算法可能有问题,个人感觉script_score 执行的时间比较靠后,此时分词阶段已经结束,company_name 已经被分词完毕,不是源表中的值了,所以这个字段不能分词。 这里例子实际意义不大,但是看到function_score 还是很强大的。

当上面的query内容变成如下内容时:

"match" : {

"_all" : {

"query" : "关键字",

"type" : "boolean",

"operator" : "AND"

}

}

相关性功能开始启用。打出的分数算法如下。

score=(weight+script_score)*相关性分数

而原来的写法,打分就是 _index[field][term].df()+weight 的值,因为相关性在filter下都是1。

下面举例来说明

4.09 是相关性的分数,接着看 6.09 是如何来的

6.09=2+4.09 其中 4.09 来自下面的配置, 很明显_score=4.09 因为上面已经提到了。

"script_score" : {

"script" : "return _score"

}

所以:score=(weight+script_score)*相关性分数。

至于相关性的分数如何打出,也很类似,请自行查看资料学习

时间: 2024-10-07 22:52:57

function_score 之script_score的相关文章

[Elasticsearch] 控制相关度 (五) - function_score查询及field_value_factor,boost_mode,max_mode参数

本章翻译自Elasticsearch官方指南的Controlling Relevance一章. function_score查询 function_score查询是处理分值计算过程的终极工具.它让你能够对所有匹配了主查询的每份文档调用一个函数来调整甚至是完全替换原来的_score. 实际上,你可以通过设置过滤器来将查询得到的结果分成若干个子集,然后对每个子集使用不同的函数.这样你就能够同时得益于:高效的分值计算以及可缓存的过滤器. 它拥有几种预先定义好了的函数: weight 对每份文档适用一个

[Elasticsearch] 控制相关度 (六) - function_score查询中的filter,functions及random_score参数

本章翻译自Elasticsearch官方指南的Looking at Time一章. 时间数据处理(Looking at Time) 如果在ES中,搜索是最常见的行为,那么创建日期柱状图(Date Histogram)肯定是第二常见的.为什么要使用日期柱状图呢? 想象在你的数据中有一个时间戳.数据是什么不重要-Apache日志事件,股票交易日期,棒球比赛时间-任何拥有时间戳的数据都能通过日期柱状图受益.当你有时间戳时,你经常会想创建基于时间的指标信息: 今年的每个月销售了多少辆车? 过去的12小时

Elasticsearch function_score 打分源代码跟踪

类注册器 IndicesModule private void registerBuiltinQueryParsers() { registerQueryParser(MatchQueryParser.class); registerQueryParser(MultiMatchQueryParser.class); registerQueryParser(NestedQueryParser.class); registerQueryParser(HasChildQueryParser.class

elasticsearch 排序 算法

如何将tfidf映射到[1,3] 区间内 (1)建立映射x→arctanx,此为一一映射,把全体实数R映射到开区间(-π/2,π/2)(2)开区间(-π/2,π/2)到开区间(0,1)只需要一个线性映射就可以,设为f(x)=ax+b,则有f(-π/2)=1且f(π/2)=3,解得a=2/π,b=2综合一下,映射x→2(arctanx)/π+2,即把全体实数映射到(1,3) 所以表达式可以写成 "script_score" : { "script" : "r

基于Elasticsearch的自定义评分算法扩展 (转)

实现思路: 重写评分方法,调整计算文档得分的过程,然后根据function_score或script_sort进行排序检索. 实现步骤: 1.新建java项目TestProject,引入Elasticsearch的jar包 2.新建package:es.testscript 3.新建类TestScriptFactory,继承NativeScriptFactory,示例: package es.testscript; import java.util.Map; import org.elastic

elasticsearch系列(七)java定义score

概述 ES支持groovy 和 java两种语言自定义score的计算方法,groovy甚至可以嵌套在请求的参数中,有点厉害,不过不在本篇讨论范围. 如何用自定义的java代码来定义score如何产生,这用到了ES的插件功能 关于es插件的相关操作,可以通过以下命令获得 ./bin elasticsearch-plugn –h 操作步骤 1.增加配置 首先需要在ES的配置中增加以下, 旧版本是 script.disable_dynamic: false 目前用的ES是5.2.2,根据日志提示,改

Elasticsearch的Groovy Script自定义评分检索

需求:以索引中的boostapp列作为评分的基础分值,同时根据carpublishtime(数据的刷新时间字段)按时间进行衰减. 基于Groovy脚本实现. 1.query脚本方式: { "fields": [ "boost", "ucarid", "boostapp", "carpublishtime" ], "query": { "function_score":

基于Elasticsearch的自定义评分算法扩展

实现思路: 重写评分方法,调整计算文档得分的过程,然后根据function_score或script_sort进行排序检索. 实现步骤: 1.新建java项目TestProject,引入Elasticsearch的jar包 2.新建package:es.testscript 3.新建类TestScriptFactory,继承NativeScriptFactory,示例: package es.testscript; import java.util.Map; import org.elastic

elasticsearch 经纬度查询

curl -XPUT "http://localhost:9200/shop/" -d '{   "mappings": {     "shop": {       "properties": {         "name": {           "type": "string"         },         "location":