实现思路:
重写评分方法,调整计算文档得分的过程,然后根据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. iOS检测网络连接状态

    官方Demo下载地址:https://developer.apple.com/library/ios/samplecode/Reachability/Reachability.zip 将Reachab ...

  2. MySQL学习笔记(二)

    二.SQL基本知识 SQL 是一种典型的非过程化程序设计语言,这种语言的特点是:只指定哪些数据被操纵,至于对这些数据要执行哪些操作,以及这些操作是如何执行的,则未被指定.非过程化程序设计语言的优点在于 ...

  3. devexpress中应用于girdviw中HtmlDataCellPrepared事件与CellEditorInitialize事件的区别

    HtmlDataCellPrepared 事件为页面展示的时候对页面做的初始化(将id变为name) ​CellEditorInitialize 事件为页面在编辑时(新增.修改)时做的初始化,如将值填 ...

  4. 使用CORS:跨域两三事

    本文为译文. 简介 APIS是可以将富网页应用串连在一起的线程.但是这个应用难以转给浏览器,跨域请求技术的选择被限制了,类似JSONP(由于安全考虑,使用会被限制),或者配置代理(设置和维护都比较头痛 ...

  5. 用C#访问Dynamic AX的WebService.

    第 1 步:创建 C# WinForm 应用程序 针对本演练,您将创建访问报表服务器 Web 服务的简单控制台应用程序.本演练假定您是在 Visual Studio 环境中进行开发的.测试范例基于VS ...

  6. Sql server 数据库 int 和guid 两者的比较

    我们公司的数据库全部是使用GUID做主键的,很多人习惯使用int做主键.所以呢,这里总结一下,将两种数据类型做主键进行一个比较. 使用INT做主键的优点: 1.需要很小的数据存储空间,仅仅需要4 by ...

  7. netlink机制

    一.netlink机制简介 netlink是一种基于网络的机制,允许在内核内部以及内核与用户之间进行通信.正式定义见RFC3549.手册见netlink(3)和netlink(7).netlink(3 ...

  8. solr5.5教程-solrconfig.xml,加载schema.xml

    布署完成后,接下来要更深入的研究solr的原理和使用. 首先进入testcore这个文件夹下面,发现这个core的conf里并没有schema.xml.那么数据格式是在哪里定义的呢? 打开 solr_ ...

  9. MVC开发Markdown编辑器(2)

    MVC开发Markdown编辑器(2) MVC Markdown 实时预览 我希望实现一个在线实时预览的Markdown编辑器,左边是编辑处,右边是实时预览界面. 准备工作 引入相关js和css 这里 ...

  10. .net4.0注册到IIS

    IIS和.netfw4.0安装顺序是从前到后,如果不小心颠倒了,无所谓. 打开程序-运行-cmd:输入一下命令重新注册IIS C:\WINDOWS\Microsoft.NET\Framework\v4 ...