实现思路:重写评分方法,调整计算文档得分的过程,然后根据function_score或script_sort进行排序检索。 实现步骤:1、新建java项目TestProject,引入Elasticsearch的jar包2、新建package:es.testscript3、新建类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); }} 4、新建类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; }} 5、打包输出jar文件TestProject.jar6、将TestProject.jar拷贝至ES目录的lib下7、修改ES配置文件elasticsearch.yml,添加:script.native: mynativescript.type: es.testscript.TestScriptFactory注:mynativescript为自定义的脚本别名。8、重启ES服务9、执行检索:function_score方式{ “query”: { “function_score”: { “query”: { “match_all”: {} }, “functions”: [ { “script_score”: { “script”: “mynativescript”, “lang”: “native”, “params”: { “p1”: 1, “fields”: “p1,p2” } } } ] } }}10、执行检索:script_sort方式{ “query”: { “match_all”: {} }, “sort”: { “_script”: { “script”: “mynativescript”, “lang”: “native”, “order”: “asc”, “type”: “string”, “params”: { “p1”: 1, “p2”: 2, “p3”: 3 } } }}11、执行检索:Nest方式之Linqvar 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对象
QueryContainer mainQuery = null;
FunctionScoreQuery funcQuery = new FunctionScoreQuery();
funcQuery.ScoreMode = FunctionScoreMode.Sum;
funcQuery.BoostMode = FunctionBoostMode.Replace;
funcQuery.MaxBoost = 1000.0f;
IFunctionScoreFunction func = new FunctionScoreFunctionsDescriptor<DTOCarInfoIndexField>().ScriptScore(s => s.Lang("native").Script("mynativescript"));
IList<IFunctionScoreFunction> list = new List<IFunctionScoreFunction>();
list.Add(func);
funcQuery.Functions = list;
mainQuery &= funcQuery;