实现思路:
重写评分方法,调整计算文档得分的过程,然后根据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;

  

 

基于Elasticsearch的自定义评分算法扩展的更多相关文章

  1. 基于elasticsearch的自定义业务告警的设计思路

    A系统与B系统之间有很多接口交互,但是有一段时间接口经常报错,作为开发如果不能第一时间知道问题且及时解决的话就会收到业务投诉,当月绩效凉凉. 如果你也有这种场景,那么你就需要一个及时告警的功能. 实现 ...

  2. 基于 HtmlHelper 的自定义扩展Container

    基于 HtmlHelper 的自定义扩展Container Intro 基于 asp.net mvc 的权限控制系统的一部分,适用于对UI层数据呈现的控制,基于 HtmlHelper 的扩展组件 Co ...

  3. 数据分析:基于Python的自定义文件格式转换系统

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  4. Elasticsearch是一个分布式可扩展的实时搜索和分析引擎,elasticsearch安装配置及中文分词

    http://fuxiaopang.gitbooks.io/learnelasticsearch/content/  (中文) 在Elasticsearch中,文档术语一种类型(type),各种各样的 ...

  5. TOTP:Time-based One-time Password Algorithm(基于时间的一次性密码算法)

    TOTP:Time-based One-time Password Algorithm(基于时间的一次性密码算法) TOTP - Time-based One-time Password Algori ...

  6. Spark 基于物品的协同过滤算法实现

    J由于 Spark MLlib 中协同过滤算法只提供了基于模型的协同过滤算法,在网上也没有找到有很好的实现,所以尝试自己实现基于物品的协同过滤算法(使用余弦相似度距离) 算法介绍 基于物品的协同过滤算 ...

  7. mahout demo——本质上是基于Hadoop的分步式算法实现,比如多节点的数据合并,数据排序,网路通信的效率,节点宕机重算,数据分步式存储

    摘自:http://blog.fens.me/mahout-recommendation-api/ 测试程序:RecommenderTest.java 测试数据集:item.csv 1,101,5.0 ...

  8. 预测算法:基于UCF的电影推荐算法

    #基于用户的推荐类算法 from math import sqrt #计算两个person的欧几里德距离 def sim_distance(prefs,person1,person2): si = { ...

  9. Spring Cloud 中自定义外部化扩展机制原理及实战

    Spring Cloud针对Environment的属性源功能做了增强, 在spring-cloud-contenxt这个包中,提供了PropertySourceLocator接口,用来实现属性文件加 ...

随机推荐

  1. 学习联系 Java阶乘相关练习

    题目一:一张纸的厚度大约是0.08mm,对折多少次之后能达到珠穆朗玛峰的高度 double hou = 0.00008; for (int i = 1; i > 0; i++) { hou = ...

  2. pxecfg&kickstart生成脚本

    em tm 00:00:00:00:00:12 10.180.1.12 255.255.255.0 173.45.34.25 255.255.255.225 173.45.34.1 em tm 00: ...

  3. css的border效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Python搭建简易HTTP服务(3.x版本和2.x版本的)

    废话不多说,我们工作时经常会用到需要HTTP服务,如果不想搞那些复杂的Apache.IIS服务器等,这时我们就可以用python帮我们搭建一个简单的服务器.操作如下: 1.下载并安装一个python: ...

  5. MyEclipse 选中属性或方法后 相同的不变色了?

    MyEclipse 选中属性或方法后 相同的不变色了? myeclipse-->windows-->java-->Editor-->Mark Occurrences 把所有的框 ...

  6. float:left居中对齐

    <div class="M1180"><div class="services"> <div class="serv_c ...

  7. 学习实践:使用模式,原则实现一个C++自动化测试程序

    个人编程中比较喜欢重构,重构能够提高自己的代码质量,使代码阅读起来也更清晰.但是重构有一个问题,就是如何保证重构后带代码实现的功能与重构前的一致,如果每次重构完成后,对此不闻不问,则会有极大的风险,如 ...

  8. C#中补0

     C#中补0 编写人:CC阿爸 2014-3-16 首先先增加两个左补齐又补齐的函数 #region 该函数动态添加空格,对齐小票 public string AddSpace(string text ...

  9. Operation is not valid due to the current state of the object.

    今天遇到一个asp.net的草郁闷的问题,看下截图 狂晕啊,在google上狂搜了一下,好在已经有大侠也遇到过这个问题了,先看下别人的解决办法吧 Operation is not valid due ...

  10. swiper 页面双向设置

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...