zoukankan      html  css  js  c++  java
  • 基于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.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 + " ");
            }
            if (params.get("fields") == null) {
                return;
            }
            paramArray = params.get("fields").toString().split(",");
            System.out.println("fields:" + params.get("fields").toString() + " ");
        }
     
        /**
         * 排序方法,计算得分
         *
         * @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 + " ");
            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对象
     QueryContainer mainQuery = null; 
    FunctionScoreQuery funcQuery = new FunctionScoreQuery(); funcQuery.ScoreMode = FunctionScoreMode.Sum; funcQuery.BoostMode = FunctionBoostMode.Replace; funcQuery.MaxBoost = 1000.0f; IFunctionScoreFunction func = new FunctionScoreFunctionsDescriptor<DTOCarInfoIndexField>().ScriptScore(s => s.Lang("native").Script("mynativescript")); IList<IFunctionScoreFunction> list = new List<IFunctionScoreFunction>(); list.Add(func); funcQuery.Functions = list; mainQuery &= funcQuery;

      

     
  • 相关阅读:
    PL/SQL Developer连接Oracle
    Oracle 11g 监听命令
    Oracle 11g的登陆问题
    PL/SQL Developer 配置和使用
    KMP应用求两个字符串的最长公共子串
    msc pool概念
    nformix调优之执行计划取得
    lsof 与fuser
    informix onstat命令收集
    各类系统上查看占cpu最多的进程
  • 原文地址:https://www.cnblogs.com/lijunhao/p/5341302.html
Copyright © 2011-2022 走看看