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
]
}
}
]
}
}