實現思路:
重寫評分方法,調整計算文檔得分的過程,而後根據function_score或script_sort進行排序檢索。
實現步驟:
一、新建java項目TestProject,引入Elasticsearch的jar包
二、新建package:es.testscript
三、新建類TestScriptFactory,繼承NativeScriptFactory,示例:
package es.testscript;
import java.util.Map;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.script.ExecutableScript;
import org.elasticsearch.script.NativeScriptFactory;
/**
* Created by lijunhao on 2016/3/29.
*/
public class TestScriptFactory implements NativeScriptFactory {
@Override
public ExecutableScript newScript(@Nullable Map<String, Object> params) {
return new TestScript(params);
}
}
四、新建類TestScript,假設計算double類型的得分,繼承AbstractDoubleSearchScript,並重寫runAsDouble方法,示例:
package es.testscript;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.index.fielddata.ScriptDocValues;
import org.elasticsearch.script.AbstractDoubleSearchScript;
import org.elasticsearch.script.AbstractLongSearchScript;
import java.util.Map;
public class TestScript extends AbstractDoubleSearchScript {
//客戶端傳遞的參與動態計算得分的參數
private String[] paramArray;
/**
* 構造函數 獲取傳入的參數
*
* @param params
*/
public TestScript(@Nullable Map<String, Object> params) {
if (params == null || params.size() == 0) {
return;
}
Set<String> keys = params.keySet();
Iterator<String> iterator = keys.iterator();
while (iterator.hasNext()) {
String key = iterator.next();
String val = params.get(key).toString();
System.out.println("key:" + key + " val:" + val + "\r\n");
}
if (params.get("fields") == null) {
return;
}
paramArray = params.get("fields").toString().split(",");
System.out.println("fields:" + params.get("fields").toString() + "\r\n");
}
/**
* 排序方法,計算得分
*
* @return
*/
@Override
public double runAsDouble() {
double defaultReturnVal = Double.parseDouble(String.valueOf(((ScriptDocValues.Longs)doc().get("id")).getValue()));
if (paramArray == null || paramArray.length == 0) {
return defaultReturnVal;
}
//根據傳入的paramArray計算得分
defaultReturnVal=defaultReturnVal+1000;
System.out.println("score:" + defaultReturnVal + "\r\n");
return defaultReturnVal;
}
}
五、打包輸出jar文件TestProject.jar
六、將TestProject.jar拷貝至ES目錄的lib下
七、修改ES配置文件elasticsearch.yml,添加:
script.native:
mynativescript.type: es.testscript.TestScriptFactory
注:mynativescript爲自定義的腳本別名。
八、重啓ES服務
九、執行檢索:function_score方式
{
"query": {
"function_score": {
"query": {
"match_all": {}
},
"functions": [
{
"script_score": {
"script": "mynativescript",
"lang": "native",
"params": {
"p1": 1,
"fields": "p1,p2"
}
}
}
]
}
}
}
十、執行檢索:script_sort方式
{
"query": {
"match_all": {}
},
"sort": {
"_script": {
"script": "mynativescript",
"lang": "native",
"order": "asc",
"type": "string",
"params": {
"p1": 1,
"p2": 2,
"p3": 3
}
}
}
}
十一、執行檢索:Nest方式之Linq
var s = new SearchDescriptor<ModelTest>().From(0).Size(20).MatchAll().SortScript(sort => sort
.Descending()
.Script("mynativescript")
.Descending()
.Params(p => p
.Add("p1", 1.1).Add("p2", 2.2)
)
.Language("native")
.Type("string")
);
//獲取請求的json字符串
string reqStr = Encoding.UTF8.GetString(client.Serializer.Serialize(s));
ISearchResponse<ModelTest> resp = client.Search<ModelTest>(s);
ModelTest[] result = resp.Documents.ToArray();
12. Nest方式之Query對象java
1 QueryContainer mainQuery = null; <br> FunctionScoreQuery funcQuery = new FunctionScoreQuery();
2 funcQuery.ScoreMode = FunctionScoreMode.Sum;
3 funcQuery.BoostMode = FunctionBoostMode.Replace;
4 funcQuery.MaxBoost = 1000.0f;
5 IFunctionScoreFunction func = new FunctionScoreFunctionsDescriptor<DTOCarInfoIndexField>().ScriptScore(s => s.Lang("native").Script("mynativescript"));
6 IList<IFunctionScoreFunction> list = new List<IFunctionScoreFunction>();
7 list.Add(func);
8 funcQuery.Functions = list;
9 mainQuery &= funcQuery;
10
11