博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于Elasticsearch的自定义评分算法扩展
阅读量:5878 次
发布时间:2019-06-19

本文共 3768 字,大约阅读时间需要 12 分钟。

实现思路:
重写评分方法,调整计算文档得分的过程,然后根据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
().ScriptScore(s => s.Lang("native").Script("mynativescript")); IList
list = new List
(); list.Add(func); funcQuery.Functions = list; mainQuery &= funcQuery;

  

 

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

你可能感兴趣的文章
Android小游戏应用---撕破美女衣服游戏
查看>>
TextKit简单示例
查看>>
网格最短路径算法(Dijkstra & Fast Marching)(转)
查看>>
最短路径算法-Dijkstra算法的应用之单词转换(词梯问题)
查看>>
软链接和硬链接详解
查看>>
HTML5 video 视频标签 常用属性
查看>>
深入理解javascript对象系列第一篇——初识对象
查看>>
Redis_master-slave模式
查看>>
qemu安装
查看>>
多媒体开发之rtmp---rtmp client 端的实现
查看>>
3.使用Maven构建Web项目
查看>>
cisco 多生成树MST笔记
查看>>
C 到 C++ 的升级(一)
查看>>
彻底卸载删除微软Win10易升方法
查看>>
移动磁盘提示使用驱动器中的光盘之前需要格式化,要如何找到数据
查看>>
Ajaxload动态加载动画生成工具的实现(ajaxload的本地移植)
查看>>
SWT/JFACE之环境配置(一)
查看>>
手把手构建LAMP
查看>>
关于outlook 保存的.msg文件打开一次之后不能再次打开的问题
查看>>
CentOS 6.6安装python3.4.3后yum不能使用的解决办法
查看>>