一.使用java编写elasticsearch 自定义插件,对应的elasticsearch版本为6.8.4,以下代码用到三个类
com.suntown.UserScriptEnginePlugin、com.suntown.MyExpertScriptEngine、com.suntown.UserUpdateFactory
package com.suntown; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.plugins.ScriptPlugin; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptEngine; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; public class UserScriptEnginePlugin extends Plugin implements ScriptPlugin{ @Override public ScriptEngine getScriptEngine(Settings settings, Collection> contexts){ return new MyExpertScriptEngine(); } }
package com.suntown; import org.elasticsearch.script.ScoreScript; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptEngine; import org.elasticsearch.script.UpdateScript; import java.util.Map; import java.util.Set; public class MyExpertScriptEngine implements ScriptEngine{ @Override public String getType() { return "myscript"; } @Override publicFactoryType compile(String scriptName, String scriptSource, ScriptContext scriptContext, Map map) { UpdateScript.Factory factory = new UserUpdateFactory(scriptName,scriptSource); return scriptContext.factoryClazz.cast(factory); } @Override public void close() { // optionally close resources } }
package com.suntown; import org.elasticsearch.script.UpdateScript; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintStream; import java.util.HashMap; import java.util.Map; public class UserUpdateFactory implements UpdateScript.Factory{ PrintStream ps = null; static int counter = 0; private String scriptName; private String scriptSource; private MapglobalMap = new HashMap<>(); public UserUpdateFactory(String _scriptName,String _scriptSource){ this.scriptName = _scriptName; this.scriptSource = _scriptSource; String userdir = System.getProperty("user.dir"); try{ ps = new PrintStream(new FileOutputStream(userdir + "\\logs\\update.log",true)); } catch (FileNotFoundException e) { e.printStackTrace(); } engine.put("ps",ps); engine.put("userdir",userdir); } ScriptEngineManager sem = new ScriptEngineManager(); ScriptEngine engine = sem.getEngineByName("javascript"); @Override public UpdateScript newInstance(Map params, Map ctx){ counter++; return new UpdateScript(params,ctx){ @Override public void execute() { java.util.HashMap hashMap = (java.util.HashMap)ctx.get("_source"); engine.put("owner",UserUpdateFactory.this); engine.put("row",hashMap); engine.put("rownum",counter); engine.put("thread",Thread.currentThread().getId()); try{ engine.eval(UserUpdateFactory.this.scriptSource); } catch (ScriptException e) { e.printStackTrace(); } } }; } }
将java代码编译后直接打包成普通的jar包,可以使用命令行
jar cvf es-user-scriptengine.jar
二.在elasticsearch中部署插件
1、切换到elasticsearch根目录,如 F:\esesarch\es684-20220311\elasticsearch-6.8.4
2、再切换到目录 F:\esesarch\es684-20220311\elasticsearch-6.8.4\modules 并新建目录 es-user-scriptengine
3、将 文件 es-user-scriptengine.jar 复制到 目录 F:\esesarch\es684-20220311\elasticsearch-6.8.4\modules\下 并新建配置文件 plugin-descriptor.properties,如下图所示
plugin-descriptor.properties 文件可从modules 目录下的其它插件子目录下拷贝过来进行修改,
主要修改上图中classname=com.suntown.UserScriptEnginePlugin 这个类就是上述 es-user-scriptengine.jar 中的类
修改完成之后、重启elasticsearch服务
三.使用postman测试插件功能
1.切换到目录 F:\esesarch\es684-20220311\elasticsearch-6.8.4\bin,运行 elasticsearch-sql-cli.bat
此时索引 zyzkwjj 中 还没有 列 rownum2
2.postman请求如下图
上图中的 "lang":"myscript" 即对应 类 com.suntown.MyExpertScriptEngine中getType()方法的返回值
3. 再使用 elasticsearch-sql-cli 查看索引zyzkwjj中的rownum2字段
发现rownum2确实更新成了从1开始递增的自增里额。