更新时间:2020-10-16 19:03
Opensearch支持两阶段排序,粗排和精排。目前cava实现的排序脚本只支持在精排阶段生效。本文只聚焦在通过cava如何编写排序脚本,至于脚本的创建和使用请参考排序脚本api使用手册,另外也可以通过我们提供的命令行工具来创建排序脚本。
与排序表达式相比,使用cava编写排序脚本具有更强的灵活性,可以定制性。用户可以在脚本中通过cava支持的语法和opensearch提供的feature lib来实现自己的业务逻辑。
为了能够使用自定义的脚本进行算分排序,用户需要实现opensearch提供的算分接口类。接口类的代码如下:
package users.scorer;
import com.aliyun.opensearch.cava.framework.OpsScoreParams;
import com.aliyun.opensearch.cava.framework.OpsScorerInitParams;
class BasicSimilarityScorer {
//可以定义一些成员变量
boolean init(OpsScorerInitParams params) {
//实现你的代码,初始请求级别的变量,比如类的成员变量
return true;
}
double score(OpsScoreParams params) {
double score = 0;
//实现你的代码,并将算分结果赋值给score
return score;
}
};
接口类BasicSimilarityScorer在包users.scorer下面,用户不能修改类名或者包名,否则编译会报错。BasicSimilarityScorer提供了init和score两个方法,用户可以在这个两个方法中实现自己的业务逻辑。
在opensearch中,对于每一个请求opensearch会先调用BasicSimilarityScorer的init方法初始化一些请求级别的变量(比如类的成员变量),该方法对于每个请求只会执行一次,如果返回失败请求终止。然后对于每个命中的且参与精排的文档,opensearch会依次调用score方法对文档进行算分,最终会根据算分结果进行排序。
init接口的输入参数为OpsScorerInitParams,通过该参数用户可以获取一些请求级别的资源。我们建议BasicSimilarityScorer的成员变量在init阶段进行初始化。
score接口的输入参数为OpsScoreParams,通过该参数用户可以获取一些请求和doc级别的资源。score接口对于每个参与算分的文档都会调用一次,所以对于请求级别的资源(比如kvpairs中的一些参数,一些feature对象的创建)尽量不要在score接口中获取(可以在init接口中获取),对于doc级别的资源可以在score接口中进行获取。
init和score的函数定义用户不能修改(比如改变返回值类型或者输入参数),否则编译的时候会报错。
package users.scorer;
import cava.lang.CString;
import com.aliyun.opensearch.cava.framework.OpsScoreParams;
import com.aliyun.opensearch.cava.framework.OpsScorerInitParams;
import com.aliyun.opensearch.cava.framework.OpsRequest;
import com.aliyun.opensearch.cava.framework.OpsKvPairs;
import com.aliyun.opensearch.cava.framework.OpsDoc;
import com.aliyun.opensearch.cava.features.similarity.TextRelevance; //引用需要使用的特征
class BasicSimilarityScorer {
TextRelevance _textRelevance; //定义算分特征作为成员变量
boolean init(OpsScorerInitParams params) {
if (!params.getDoc().requireAttribute("shop_margin")) { //算分中使用的属性字段,需要在init接口中声明
return false;
}
_textRelevance = TextRelevance.create(params, "default", "name"); //算分特征在init接口中声明
return true;
}
double score(OpsScoreParams params) {
float shopMargin = params.getDoc().docFieldFloat("shop_margin"); //获取文档中字段的值
float textScore = _textRelevance.evaluate(params); //计算特征分数
double score = textScore * 30.0 + shopMargin;
return score;
}
}
在文档使用中是否遇到以下问题
更多建议
匿名提交