Elasticsearch 实现自定义排序插件(转载)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch 实现自定义排序插件(转载)相关的知识,希望对你有一定的参考价值。

参考技术A 转自: http://www.cnblogs.com/xffy1028/p/6383676.html

插件入口:

package ttd.ugc.plugin;

import org.elasticsearch.plugins.Plugin;

import org.elasticsearch.script.ScriptModule;

/**

* Created by jin_h on 2017/1/9.

*/

public class NativeScriptPlugin  extends Plugin

@Override

public String name()

return "comment-default-sort";



@Override

public String description()

return "comment-default-sort";



public void onModule(ScriptModule module)

//comment-default-sort排序算法的名称

module.registerScript("comment-default-sort", CommentDefaultSortScriptFactory.class);





插件具体实现:

package ttd.ugc.plugin;

import org.elasticsearch.common.Nullable;

import org.elasticsearch.index.fielddata.ScriptDocValues;

import org.elasticsearch.script.AbstractDoubleSearchScript;

import org.elasticsearch.script.AbstractLongSearchScript;

import org.elasticsearch.script.ExecutableScript;

import org.elasticsearch.script.NativeScriptFactory;

import org.elasticsearch.search.lookup.LeafDocLookup;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Map;

/**

* Created by jin_h on 2017/1/9.

*/

public class CommentDefaultSortScriptFactory implements NativeScriptFactory

@Override

public ExecutableScript newScript(@Nullable Map map)

return new CustomScript(map);



@Override

public boolean needsScores()

return false;



protected class CustomScript extends AbstractDoubleSearchScript

//params 通过外部传入的参数方式进行排序干预

public CustomScript(@Nullable Map params)



@Override

public double runAsDouble()

//三种获取文档方式.

//((ScriptDocValues.Longs)doc().get("wordnumber")).getValue()

//(int)source().get("wordnumber");

//this.docFieldLongs("wordnumber");

double wordNumber;

double commentTime;

double useDate;

double numPicture;

double feedBack;

try

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

String today = sdf.format(new Date());

if (source().get("wordnumber") == null)

wordNumber = 0;

else

wordNumber = (int)source().get("wordnumber");

if (wordNumber >= 100)

wordNumber = 1;

else if (wordNumber >= 70)

wordNumber = 0.9;

else if (wordNumber >= 60)

wordNumber = 0.8;

else if (wordNumber >= 50)

wordNumber = 0.7;

else if (wordNumber >= 40)

wordNumber = 0.6;

else if (wordNumber >= 30)

wordNumber = 0.5;

else if (wordNumber >= 20)

wordNumber = 0.4;

else if (wordNumber >= 10)

wordNumber = 0.3;

else if (wordNumber >= 5)

wordNumber = 0.2;

else if (wordNumber >= 1)

wordNumber = 0.1;

else

wordNumber = 0;





if (source().get("imgcount") == null)

numPicture = 0;

else

numPicture = (int)source().get("imgcount");

if (numPicture >= 10)

numPicture = 1;

else if (numPicture >= 9)

numPicture = 0.9;

else if (numPicture >= 8)

numPicture = 0.8;

else if (numPicture >= 7)

numPicture = 0.7;

else if (numPicture >= 6)

numPicture = 0.6;

else if (numPicture >= 5)

numPicture = 0.5;

else if (numPicture >= 4)

numPicture = 0.4;

else if (numPicture >= 3)

numPicture = 0.3;

else if (numPicture >= 2)

numPicture = 0.2;

else if (numPicture >= 1)

numPicture = 0.1;

else

numPicture = 0;





if (source().get("useful") == null)

feedBack = 0;

else

feedBack = (int)source().get("useful");

if (feedBack >= 10)

feedBack = 1;

else if (feedBack >= 9)

feedBack = 0.9;

else if (feedBack >= 8)

feedBack = 0.8;

else if (feedBack >= 7)

feedBack = 0.7;

else if (feedBack >= 6)

feedBack = 0.6;

else if (feedBack >= 5)

feedBack = 0.5;

else if (feedBack >= 4)

feedBack = 0.4;

else if (feedBack >= 3)

feedBack = 0.3;

else if (feedBack >= 2)

feedBack = 0.2;

else if (feedBack >= 1)

feedBack = 0.1;

else

feedBack = 0;





commentTime =source().get("cmtdate")==null?-1:(sdf.parse(today).getTime() - sdf.parse(source().get("cmtdate").toString()).getTime())/(24*60*60*1000);

if (commentTime >= 620)

commentTime = 0.1;

else if (commentTime >= 360)

commentTime = 0.2;

else if (commentTime >= 180)

commentTime = 0.3;

else if (commentTime >= 120)

commentTime = 0.4;

else if (commentTime >= 90)

commentTime = 0.5;

else if (commentTime >= 60)

commentTime = 0.6;

else if (commentTime >= 30)

commentTime = 0.7;

else if (commentTime >= 14)

commentTime = 0.8;

else if (commentTime >= 7)

commentTime = 0.9;

else if (commentTime >= 0)

commentTime = 1;

else

commentTime = 0;



useDate =source().get("usedate")==null?-1: (sdf.parse(today).getTime() -  sdf.parse(source().get("usedate").toString()).getTime())/(24*60*60*1000);

if (useDate >= 620)

useDate = 0.1;

else if (useDate >= 360)

useDate = 0.2;

else if (useDate >= 180)

useDate = 0.3;

else if (useDate >= 120)

useDate = 0.4;

else if (useDate >= 90)

useDate = 0.5;

else if (useDate >= 60)

useDate = 0.6;

else if (useDate >= 30)

useDate = 0.7;

else if (useDate >= 14)

useDate = 0.8;

else if (useDate >= 7)

useDate = 0.9;

else if (useDate >= 0)

useDate = 1;

else

useDate = 0;



double iw_wordNumber = 0.3;

double iw2_commentTime = 0.2;

double iw3_useDate = 0.2;

double iw4_numPicture = 0.15;

double iw5_feedBack = 0.15;

double sumW = iw_wordNumber + iw2_commentTime + iw3_useDate + iw4_numPicture + iw5_feedBack;

double sumScore = wordNumber * iw_wordNumber + commentTime * iw2_commentTime + useDate * iw3_useDate + numPicture * iw4_numPicture + feedBack * iw5_feedBack;

return (sumScore / sumW);

catch (Exception ex)

ex.printStackTrace();

return -1;//this.docFieldLongs("wordnumber").getValue();







ElasticSearch 5.4 自定义插件

  ElasticSearch 做为数据仓库处理速度确实很强,但是很多和业务相关的函数ElasticSearch怎么支持的,通过查询发现,ElasticSearch支持自定义插件(相当于自定义函数),通过自定义插件,开发人员可以实现各种业务相关的函数定义供相关人员使用。

1.   ElasticSearch  自定义插件编写

   后续补充。

2.  ElasticSearch  自定义插件打包

  2.1  自定义插件开发完成后,需要增加“plugin-descriptor.properties”配置文件,需要配置的信息有:

    • description:插件的描述信息,用来描述该插件的作用
    • version:插件的版本信息
    • name:插件在elasticsearch plugin中显示的名称
    • classname:插件的入口,需要实现Iplugin接口
    • java.version:插件采用的java版本信息
    • elasticsearch.version:插件发布到elasticsearch的那个特定版本上
    • 可选属性(作用暂时未知)
      • site:true表示发布为网站形式,_site目录下的内容将会起作用。
      • jvm:true表示设置的classname对应的类将会被加载,对于依赖的资源,配置等信息也需要打包成jar

  2.2  生成该文件后,将该properties文件与jar包放到一个名称为elasticsearch的文件夹中,然后将该elasticsearch文件夹压缩成zip文件,完成插件的打包过程

3.  ElasticSearch  自定义插件部署

  3.1  在elasticsearch服务器上进入elasticsearch的根目录;下列命令的执行需要使用管理员权限执行。

  3.2  在根目录下执行./bin/elasticsearch-plugin list  展示所有的插件

    

      3.3  执行./bin/elasticsearch-plugin install file:///abstractDirectory/zipfile.zip 来安装插件,其中file://后跟的是zip文件的绝对目录。

            

     3.4  如果要删除不再使用的插件,执行./bin/elasticsearch-plugin remove plugin.name,如下图中plugin.name名称为sql,此sql为plugin-description.properties中配置的name。

    

4.  ElasticSearch 自定义插件的使用

  本例子安装的插件是elasticsearch-sql插件,详见:https://github.com/NLPchina/elasticsearch-sql/。 使用方法为curl -XGET http://xx.xx.xx.xx:9200/_sql?sql=select * from indexName,sql参数后边跟的是标准sql语句,该插件会自动转化为elasticsearch 查询语言去es执行。详细使用方法见官网。

 

      

以上是关于Elasticsearch 实现自定义排序插件(转载)的主要内容,如果未能解决你的问题,请参考以下文章

基于Elasticsearch的自定义评分算法扩展 (转)

基于Elasticsearch的自定义评分算法扩展 (转)

ElasticSearch 5.4 自定义插件

Elasticsearch自定义过滤插件实现复杂逻辑过滤

ElasticSearch的自定义插件

基于Elasticsearch的自定义评分算法扩展