es painless 排序_Elasticsearch中使用painless实现评分「建议收藏」

使用Elasticsearch(ES)作为搜索引擎时我们常常需要根据文档的属性值自定义它们的排序,为用户提供高质量的搜索结果。以下内容已在ElasticSearch7.1.1Linux集群中测试。ES中的rest_api中提供了自定义评分选项,分别为function_score下的function_script和script_score。其中function_score可以用于简单的评分需…

大家好,又见面了,我是你们的朋友全栈君。

使用Elasticsearch(ES)作为搜索引擎时我们常常需要根据文档的属性值自定义它们的排序,为用户提供高质量的搜索结果。

以下内容已在 ElasticSearch 7.1.1 Linux 集群中测试。

ES中的rest_api中提供了自定义评分选项,分别为function_score下的function_script和script_score。其中function_score可以用于简单的评分需求,但是当我们要加入文档PageRank的影响,加入时间衰减因子,且根据文档类型给予不同的乘法因子等,简单的function_script就无能为力了;而script_score,也就是本文将介绍的内容,可以用于满足复杂的,高度定制化的评分需求。

painless语言可以采用动态隐式类型声明,类似groovy的语法,如:

def i = 1;

也可以使用静态显式类型,类似Java的语法:

int i = 1;

基于明确好于隐式的原则,接下来实例中采用强类型的Java语法。

Java ES前端代码:

/**这里的script-id为我们通过ES的_scripts API储存在ES集群中的值一下为Kibana devtools中更新和获取最新值方法,更新实时生效下次请求就会有最新的排序结果更新方法(script-id是自已定的script的名字):POST _scripts/script-id{“script”: {“lang” : “painless”,”source” : “// Your script score code here “}}获取方法:GET _scripts/script-id*/

// 在Java 中使用stored script_score:Map scriptParams = new HashMap() {

private static final long serialVersionUID = 1L;

{

put(“now”, new Date().toInstant().toEpochMilli());

}

};

Script script = new Script(ScriptType.STORED, null, “script-id”, scriptParams);

ScriptScoreFunctionBuilder scriptScoreBuilder = ScoreFunctionBuilders.scriptFunction(script);

FunctionScoreQueryBuilder functionScoreBuilder = QueryBuilder

.functionScoreQuery(/* originalBuilder */, scriptScoreBuilder)

.boostMode(CombineFunction.REPLACE);

painless示例,在下面的脚本中我们用painless脚本实现了等价于内置高斯衰减的函数

// params、_score和doc是特殊变量

// params用来获取在(Java)代码中生成得到的值,// 如new Date()long now = params[‘now’]; // 从params获取now变量的值,这个值在每次接受请求时 // 由Java生成,比如:new Date().toInstant().toEpochMilli() // 处于安全考虑,painless中不允许new Date()的使用。

// _score是当前文档的BM25评分。// 以下painless代码实现了获取当前时间和根据当前时间更新评分。

// doc是当前文档// 可以通过doc[‘SomeProp’]获取文档的SomeProp属性的包装对象// 通过doc[‘SomeProp’].value获取文档的SomeProp属性真实值

// 假设索引中有类型为Date的pubDate字段,记录的文档的发表时间。// 用doc[‘pubDate’].value获取值long docTime = doc[‘pubDate’].value.toInstant().toEpochMilli();

long docVal = now – docTime;

long year = 1000L * 3600 * 24 * 365; // year in milliseconds

long gaussScale = year * 1.5;

long gaussOffset = year * 0;

double gaussDecay = 0.5;

double sigmaSquare = – (Math.pow(gaussScale, 2) / (2 * Math.log(gaussDecay)));

double gaussMultiplier = Math.exp(-1 * Math.pow(Math.max(0, Math.abs(docTime – now) – gaussOffset), 2) / 2 / sigmaSquare);

return _score * gaussMultiplier;

参考

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/126362.html原文链接:https://javaforall.net

(0)
上一篇 2022年4月7日 下午5:40
下一篇 2022年4月7日 下午6:00


相关推荐

  • 详解react hooks(含高阶组件)

    详解react hooks(含高阶组件)一 面试中出现的关于 hooks 的题目 1 简单介绍下什么是 hooks hooks 的优点 ReactHooks 是 react 团队研发的 它主要有两方面作用 用于在函数组件中引入状态管理和生命周期方法取代高阶组件和 renderprops 来实现抽象和可重用性在 hooks 出现之前 只有在类组件中可以使用本地状态管理和生命周期方法 函数组件只能是无状态组件 因为函数组件使用便利优雅 已经被广泛使用 后期如果函数组件需要承担一些副作用 只能把它重构成类组件 hooks 的出现就不需要重构了 它帮助函数组

    2025年10月4日
    5
  • tomcat修改端口号失效

    tomcat修改端口号失效原因使用 startup bat 默认启动 CATALINA HOME 路径下的 tomcat 但我们想要启动的是另外一个 tomcat 解决方法先在 tomcat 的启动处 bin startup bat 中将 ifnot CATALINA HOME gotogotHome 注释掉 这里的注释得用 rem 到 server xml 文件修改所需的端口号 重新启动 tomcat

    2026年3月19日
    2
  • 线性代数五阶行列式计算(行列式的计算方法)

    由于线程代数的学习主要是为H.264算法的学习做铺垫,所以行列式的计算法就过多展开,详细请查看【线性代数(5)】等和,三叉型,反对称行列式计算及python代码辅助验证例1:化为上三角(就硬算)巧妙使用展开式例3:反对称行列式反对称行列式描述:主对角线全为0,上下位置对应成相反数(aij=−ajia_{ij}=−a_{ji}aij​=−aji​)对称行列式描述:主对角线没有要求,上下位置相等(aij=ajia_{ij}=a_{ji}aij​=aji​)定理:

    2022年4月9日
    971
  • 数据库的存储系列———将图片存储到数据库

    数据库的存储系列———将图片存储到数据库数据库的存储—系列———将图片存储到数据库在很多时候我们都使用数据库才存储我们的数据,然而我们通常在数据库里面存放的数据大多都支持数或者是一些字符,那么如果我们想在数据库里面存放图片,那么应该要怎么做的?第一,我们可以将图片所在的路径或者URI存入到数据库里面,这样简单方便。不过这样的缺点也很显然,就是图片路径改变的时候,我们没有办法通过数据库来获取这一张图片。所以这种方法并不是我们所想要的将图片存

    2022年7月12日
    20
  • LBD 原理

    LBD 原理线特征 LBD 算法 三 参考文章 Anefficienta nbsp ReinhardKoch nbsp 第二

    2026年3月19日
    2
  • kestrel服务器性能,深入理解kestrel的应用

    kestrel服务器性能,深入理解kestrel的应用原标题 深入理解 kestrel 的应用 1 前言之所以写本文章 是因为在我停止维护多年前写的 NetworkSocke 组件两年多来 还是有一些开发者在关注这个项目 我希望有类似需求的开发者明白为什么要停止更新 可以使用什么更好的方式来替换 其实很大原因是我把时间花在开发 WebApiClient 上面了 那时 netcore 还没有生下来 asp net 除了蜗居在 iis 里处理 http 其它什么也不能干 而

    2026年3月19日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号