实现思路:
重写评分方法,调整计算文档得分的过程,然后根据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. linux 关闭系统提示声音

    关闭Linux 提示声音:   rmmod pcspkr      //永久关闭 在/etc/modprobe.d/blacklist文件最后加上 blacklist pcspkr

  2. python列表的常用操作方法

    主要介绍了Python中列表(List)的详解操作方法,包含创建.访问.更新.删除.其它操作等,需要的朋友可以参考下. 1.创建列表.只要把逗号分隔的不同的数据项使用方括号括起来即可 List = [ ...

  3. Compass是什么

    Compass是一个强大的Sass框架,他的设计目标是顺畅.搞笑地装扮互联网,使用它的人可以写出可维护性更高的样式表. Compass由三个主要部分组成:混混合器和实用工具类库,能够集成到应用开发环境 ...

  4. APUE第五章:标准IO库

    5.2流和file对象 #include <wchar.h> int fwide(FILE *fp, int mode); Returns: positive if stream is w ...

  5. HTTP MIME类型即HttpResponse.ContentType属性值列表

    MIME-Typ Dateiendung(en) Bedeutung application/acad *.dwg AutoCAD-Dateien (nach NCSA) application/ap ...

  6. std::cout彩色输出

    Mac OS效果 Windows 效果 想写这个东西其实是因为最近要写个命令行的工具,但是有个问题是什么呢?就是传统的那个黑漆漆的窗口看起来很蛋疼.并且完全看不到重点,于是就想起 来这么一个东西.相对 ...

  7. 盒子的padding不影响总的大小css代码

    -moz-box-sizing: border-box; /*Firefox3.5+*/-webkit-box-sizing: border-box; /*Safari3.2+*/-o-box-siz ...

  8. Android IOS WebRTC 音视频开发总结(八)-- ios上移植webRTCDemo

    这篇文章主要介绍ios webrtcdemo的实现及相关注意事项,转载请说明出处(博客园RTC.Blacker) 前面很多人问webrtc android下有webrtcdemo,ios上怎么找不到, ...

  9. AnyCAD三维控件场景节点详解

    SceneNode是AnyCAD三维图形平台的AnyViz显示引擎的核心对象之一,只有放在场景管理器(SceneManager)里的节点才能被显示引擎所显示. 1.   节点分类 SceneNode是 ...

  10. 音乐社交APP源码 V1.1

    1.关于音乐曲库,对接的是百度音乐,会自动随搜索链接百度曲库2.便捷聊天,采用xmpp基本架构.3.加入和整理了群聊天.4.分布式聊天,喜欢该专辑直接进入聊天,喜欢该音乐的进入聊天.5.采用兴趣社交和 ...