In this tutorial, we will create a plugin to take two parameters field name and a numeric factor and multiply them together. Then, we will use the output of this plugin as a custom scorer.
Codebase
Each ElasticSearch Plugin should contain (at least) two classes: A factory class and a class to implement the functionality
└── src └── myplugin ├── MyPluginFactory.java └── MyPlugin.java
Sample code for the factory class:
package myplugin;
import java.util.Map;
import org.elasticsearch.script.ExecutableScript;
import org.elasticsearch.script.NativeScriptFactory;
public class MyPluginFactory implements NativeScriptFactory{
@Override
public ExecutableScript newScript(Map<String, Object> params) {
return new MyPlugin(params);
}
}
Sample code for the implementation class:
package myplugin;
import java.util.Map;
import org.elasticsearch.script.AbstractDoubleSearchScript;
import org.elasticsearch.index.fielddata.ScriptDocValues;
public class MyPlugin extends AbstractDoubleSearchScript{
Double factor;
String fieldName;
public MyPlugin(Map<String, Object> params){
factor = Double.parseDouble( (String) params.get("factor"));
fieldName =(String) params.get("field");
}
@Override
public double runAsDouble() {
Double fieldVal = this.docFieldDoubles(fieldName).getValue();
return factor * fieldVal;
}
}
Install plugin to ElasticSearch
#compile and package javac -cp /usr/share/elasticsearch/lib/elasticsearch-1.0.1.jar -d bin/ src/myplugin/*.java; cd bin; jar cf ../my-example-plugin.jar myplugin/*.class; cd ..; tree ├── my-example-plugin.jar ├── bin │ └── myplugin │ ├── MyPlugin.class │ └── MyPluginFactory.class └── src └── myplugin ├── MyPluginFactory.java └── MyPlugin.java #create plugin folder and move the jar to it #RUN AS ROOT mkdir /usr/share/elasticsearch/plugins/myplugin; cp my-example-plugin.jar /usr/share/elasticsearch/plugins/myplugin; #register the plugin to make it visible to elasticsearch echo " script.native.myplugin.type: myplugin.MyPluginFactory" >> /etc/elasticsearch/elasticsearch.yml #restart ElasticSearch to re-load the plugin service elasticsearch restart
Sample Request
curl -XPOST 'http://localhost:9200/items/_search?fields=_score,popularity' -H 'Content-Type: application/x-www-form-urlencoded' --data '{ "query": { "function_score": { "script_score": { "script": "myplugin", "lang": "native", "params": { "field": "popularity", "factor": "3.0" } } } } }'
Expected output:
Notice that score is 3* popularity
{
"took": 6,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 2.97159,
"hits": [
{
"_index": "items",
"_type": "269183",
"_id": "_update",
"_score": 1.5,
"fields": {
"popularity": [
0.5
]
}
}
]
}
}