受欢迎的博客标签

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

Published
实现思路: 重写评分方法,调整计算文档得分的过程,然后根据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.elasticsearch.common.Nullable; import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.NativeScriptFactory;   /**  * Created by lijunhao on 2016/3/29.  */ public class TestScriptFactory implements NativeScriptFactory {     @Override     public ExecutableScript newScript(@Nullable Map<String, Object> params) {         return new TestScript(params);     } }   4、新建类TestScript,假设计算double类型的得分,继承AbstractDoubleSearchScript,并重写runAsDouble方法,示例: package es.testscript;   import java.util.Iterator; import java.util.Map; import java.util.Set;   import org.elasticsearch.common.Nullable; import org.elasticsearch.index.fielddata.ScriptDocValues; import org.elasticsearch.script.AbstractDoubleSearchScript; import org.elasticsearch.script.AbstractLongSearchScript;   import java.util.Map;   public class TestScript extends AbstractDoubleSearchScript {     //客户端传递的参与动态计算得分的参数     private String[] paramArray;       /**      * 构造函数 获取传入的参数      *      * @param params      */     public TestScript(@Nullable Map<String, Object> params) {         if (params == null || params.size() == 0) {             return;         }         Set<String> keys = params.keySet();         Iterator<String> iterator = keys.iterator();         while (iterator.hasNext()) {             String key = iterator.next();             String val = params.get(key).toString();             System.out.println("key:" + key + " val:" + val + "\r\n");         }         if (params.get("fields") == null) {             return;         }         paramArray = params.get("fields").toString().split(",");         System.out.println("fields:" + params.get("fields").toString() + "\r\n");     }       /**      * 排序方法,计算得分      *      * @return      */     @Override     public double runAsDouble() {         double defaultReturnVal = Double.parseDouble(String.valueOf(((ScriptDocValues.Longs)doc().get("id")).getValue()));         if (paramArray == null || paramArray.length == 0) {             return defaultReturnVal;         }         //根据传入的paramArray计算得分         defaultReturnVal=defaultReturnVal+1000;         System.out.println("score:" + defaultReturnVal + "\r\n");         return defaultReturnVal;     } }   5、打包输出jar文件TestProject.jar 6、将TestProject.jar拷贝至ES目录的lib下 7、修改ES配置文件elasticsearch.yml,添加: script.native:     mynativescript.type: es.testscript.TestScriptFactory 注:mynativescript为自定义的脚本别名。 8、重启ES服务 9、执行检索:function_score方式 {   "query": {     "function_score": {       "query": {         "match_all": {}       },       "functions": [         {           "script_score": {             "script": "mynativescript",             "lang": "native",             "params": {               "p1": 1,               "fields": "p1,p2"             }           }         }       ]     }   } } 10、执行检索:script_sort方式 {   "query": {     "match_all": {}   },   "sort": {     "_script": {       "script": "mynativescript",       "lang": "native",       "order": "asc",       "type": "string",       "params": {         "p1": 1,         "p2": 2,         "p3": 3       }     }   } } 11、执行检索:Nest方式之Linq var s = new SearchDescriptor<ModelTest>().From(0).Size(20).MatchAll().SortScript(sort => sort                      .Descending()                      .Script("mynativescript")                      .Descending()                      .Params(p => p                          .Add("p1", 1.1).Add("p2", 2.2)                      )                      .Language("native")                      .Type("string")                  ); //获取请求的json字符串 string reqStr = Encoding.UTF8.GetString(client.Serializer.Serialize(s)); ISearchResponse<ModelTest> resp = client.Search<ModelTest>(s); ModelTest[] result = resp.Documents.ToArray();   12. Nest方式之Query对象 1 QueryContainer mainQuery = null; <br> FunctionScoreQuery funcQuery = new FunctionScoreQuery(); 2 funcQuery.ScoreMode = FunctionScoreMode.Sum; 3 funcQuery.BoostMode = FunctionBoostMode.Replace; 4 funcQuery.MaxBoost = 1000.0f; 5 IFunctionScoreFunction func = new FunctionScoreFunctionsDescriptor<DTOCarInfoIndexField>().ScriptScore(s => s.Lang("native").Script("mynativescript")); 6 IList<IFunctionScoreFunction> list = new List<IFunctionScoreFunction>(); 7 list.Add(func); 8 funcQuery.Functions = list; 9 mainQuery &= funcQuery; 10 11 .