基于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 + "\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对象
 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;

  

 

转载于:https://www.cnblogs.com/lijunhao/p/5341302.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值