本文实现ElasticSearch6.5的插件编写,因为ElasticSearch6.0和6.5在插件上做了细化
核心代码
package org.elasticsearch.plugins;
import org.apache.lucene.index.LeafReaderContext;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.script.ScoreScript;
import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.script.ScriptEngine;
import org.elasticsearch.search.lookup.SearchLookup;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
public class ScorePlugin extends Plugin implements ScriptPlugin {
@Override
public ScriptEngine getScriptEngine(Settings settings, Collection<ScriptContext<?>> contexts) {
return new ScorePlugin.MyExpertScriptEngine();
}
private static class MyExpertScriptEngine implements ScriptEngine {
private static double distance(String s1, String s2) {
int counter = 0;
for (int k = 0; k < s1.length();k++) {
if(s1.charAt(k) != s2.charAt(k)) {
counter++;
}
}
return 100-counter;
}
@Override
public String getType() {
return "expert_scripts";
}
@Override
public <T> T compile(String scriptName, String scriptSource,
ScriptContext<T> context, Map<String, String> params) {
if (context.equals(ScoreScript.CONTEXT) == false) {
throw new IllegalArgumentException(getType()
+ " scripts cannot be used for context ["
+ context.name + "]");
}
if ("pure_df".equals(scriptSource)) {
ScoreScript.Factory factory = PureDfLeafFactory::new;
return context.factoryClazz.cast(factory);
}
throw new IllegalArgumentException("Unknown script name "
+ scriptSource);
}
@Override
public void close() {
// optionally close resources
}
private static class PureDfLeafFactory implements ScoreScript.LeafFactory {
private final Map<String, Object> params;
private final SearchLookup lookup;
private final String field;
private final String term;
private PureDfLeafFactory(
Map<String, Object> params, SearchLookup lookup) {
if (params.containsKey("field") == false) {
throw new IllegalArgumentException(
"Missing parameter [field]");
}
if (params.containsKey("term") == false) {
throw new IllegalArgumentException(
"Missing parameter [term]");
}
this.params = params;
this.lookup = lookup;
field = params.get("field").toString();
term = params.get("term").toString();
}
@Override
public boolean needs_score() {
return false; // Return true if the script needs the score
}
@Override
public ScoreScript newInstance(LeafReaderContext context)
throws IOException {
return new ScoreScript(params, lookup, context) {
final String field = params.containsKey("field")?(String)params.get("field"):"";
final String text = params.containsKey("term")?(String)params.get("term"):"";
@Override
public double execute() {
String test = (String) lookup.source().get(field);
return distance(text,test);
}
};
}
}
}
}
Kibana查询语句
GET test_index/_search
{
"from": 0,
"size": 10,
"min_score":80,
"query": {
"function_score": {
"query": {
"match_all": {}
},
"functions": [
{
"script_score": {
"script": {
"source": "pure_df",
"lang": "expert_scripts",
"params": {
"field": "title",
"term": "1101100001110011111110001101111000000101010000111"
}
}
}
}
]}
},
"sort": [
{
"_score": {
"order": "desc"
}
}
]
}