es6不支持native
插件開發中會有一些變化
需要實現ScriptEngine接口
插件入口
package com.esplugin.demo; import java.util.Collection; 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; public class DemoPlugin extends Plugin implements ScriptPlugin { @Override public ScriptEngine getScriptEngine(Settings settings, Collection<ScriptContext<?>> contexts) { return new MyScriptEngine(); }
}
其中getType方法中return的就是script的lang;插件名稱在complile中用if判斷,scriptSource為插件名稱,執行插件邏輯
package com.esplugin.demo; import java.io.IOException; import java.util.Map; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.lucene.index.LeafReaderContext; import org.elasticsearch.script.ScriptContext; import org.elasticsearch.script.ScriptEngine; import org.elasticsearch.script.SearchScript; public class MyScriptEngine implements ScriptEngine { private final static Logger logger = LogManager.getLogger(MyScriptEngine.class); @Override public String getType() { return "myscript"; } @Override public <T> T compile(String scriptName, String scriptSource, ScriptContext<T> context, Map<String, String> params) { logger.info("use params the scriptName {} ,scriptSource {}, context {},params {}",scriptName,scriptSource,context.name,params.entrySet()); if (!context.equals(SearchScript.CONTEXT)) { throw new IllegalArgumentException(getType() + " scripts cannot be used for context [" + context.name + "]"); } if("demoPlugin".equals(scriptSource)){ SearchScript.Factory factory = (p, lookup) -> new SearchScript.LeafFactory() { final String field = p.containsKey("field")?(String)p.get("field"):""; final String text = p.containsKey("text")?(String)p.get("text"):""; @Override public SearchScript newInstance(LeafReaderContext context) throws IOException { return new SearchScript(p, lookup, context) { @Override public double runAsDouble() { final String test = (String) lookup.source().get(field); if (test.indexOf(text) >= 0){ return 1.0D; } return Double.MAX_VALUE; } }; } @Override public boolean needs_score() { return false; } }; return context.factoryClazz.cast(factory); } throw new IllegalArgumentException("Unknown script name " + scriptSource); } @Override public void close() { // optionally close resources } }
查詢如下,lang中為getType中的renturn值,source為插件名,params為參數
GET index/_search
{ "query": { "function_score": { "query": { "match_all": {} }, "script_score": { "script": { "source": "demoPlugin", "lang": "myscript", "params": { "field": "test", "text": "1" } } } } } }
或者
{ "_source": [ "*" ], "query": { "match_all": {} }, "script_fields": { "myscore": { "script": { "source": "demoPlugin", "lang": "myscript", "params": { "field": "test", "text": "1" } } } } }
或者
{ "query": { "match_all": {} }, "rescore": [ { "window_size": 2000, "query": { "rescore_query": { "function_score": { "script_score": { "script": { "source": "demoPlugin", "lang": "myscript", "params": { "field": "test", "text": "1" } } } } }, "query_weight" : 0, "rescore_query_weight" : 1 } } ] }
多個腳本分數進行rescore,如下,其中rescore_mode可以為multiply相乘(默認)、sum累加、avg平均數、max、min、first、只使用第一個函數的結果。
{ "query": { "match_all": {} }, "rescore": [ { "window_size": 2000, "query": { "rescore_query": { "function_score": { "score_mode": "sum", "functions": [ { "script_score": { "script": { "source": "demoPlugin", "lang": "myscript", "params": { "field": "test", "text": "1" } } } }, { "script_score": { "script": { "source": "return -9", "lang": "painless" } } } ] } }, "query_weight": 0, "rescore_query_weight": 1 } } ] }
無關內容:score_query的使用
{ "query": { "match": { "title": { "query": "quick brown fox", "minimum_should_match": "30%" } } }, "rescore": { "window_size": 50, "query": { "rescore_query": { "match_phrase": { "title": { "query": "quick brown fox", "slop": 50 } } } } } }