ElasticSearch High Level REST API(5)使用模板搜索
ElasticSearch Rest高级API 提供了多种搜索方式,除了前面讲到的search查询,ElasticSearch 还提供了通过模板搜索查询。
我们可以通过脚本预选注册模板,在注册模板时定义一个模板名称。在查询时通过模板名称调用该模板。
注册模板
@Autowired
private RestClient restClient;
@GetMapping("template/register")
public String registerTemplate() {
String template = "{\n" +
" \"script\":{\n" +
" \"lang\":\"mustache\",\n" +
" \"source\":{\n" +
" \"query\":{\n" +
" \"match\":{\n" +
" \"{{key}}\":\"{{value}}\"\n" +
" }\n" +
" },\n" +
" \"size\":\"{{size}}\"\n" +
" }\n" +
" }\n" +
"}";
Request scriptRequest = new Request("POST", "_scripts/title_search");
scriptRequest.setJsonEntity(template);
try {
Response response = restClient.performRequest(scriptRequest);
//restClient.close();
return JSON.toJSONString(response);
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
{
"entity":{
"chunked":false,
"content":{
},
"contentLength":21,
"contentType":{
"buffer":{
"empty":false,
"full":false
},
"elements":[
{
"name":"application/json",
"parameterCount":1,
"parameters":[
{
"name":"charset",
"value":"UTF-8"
}
]
}
],
"name":"content-type",
"value":"application/json; charset=UTF-8",
"valuePos":13
},
"repeatable":false,
"streaming":true
},
"headers":[
{
"$ref":"$.entity.contentType"
},
{
"buffer":{
"empty":false,
"full":false
},
"elements":[
{
"name":"21",
"parameterCount":0,
"parameters":[
]
}
],
"name":"content-length",
"value":"21",
"valuePos":15
}
],
"host":{
"hostName":"192.168.165.239",
"port":9200,
"schemeName":"http"
},
"requestLine":{
"method":"POST",
"protocolVersion":{
"major":1,
"minor":1,
"protocol":"HTTP"
},
"uri":"_scripts/title_search"
},
"statusLine":{
"protocolVersion":{
"$ref":"$.requestLine.protocolVersion"
},
"reasonPhrase":"OK",
"statusCode":200
},
"warnings":[
]
}
由于ElasticSearch 6.5-7.1版本的高级Rest API中暂时还没有提供用于注册模板的存储脚本,所以本示例中使用的低级REST客户端。本示例中注册了一个名为title_search
的模板
有了这个模板就可以通过title_search
去调用,动态的将查询参数添加到模板中去。模板调用示例如下:
@GetMapping("template/search")
public void templateSearch() {
try {
SearchTemplateRequest request = new SearchTemplateRequest();
request.setRequest(new SearchRequest("test"));
request.setScriptType(ScriptType.STORED);
request.setScript("title_search");
Map<String, Object> params = new HashMap<>();
params.put("key", "name");
params.put("value", "Joe.Ye");
params.put("size", 5);
request.setScriptParams(params);
try {
SearchTemplateResponse searchTemplateResponse = client.searchTemplate(request, RequestOptions.DEFAULT);
SearchHit[] hits = searchTemplateResponse.getResponse().getHits().getHits();
for (SearchHit hit : hits) {
log.info(hit.getSourceAsString());
}
client.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
{"name":"Joe.Ye","email":"yezhou@yezhou.org","homepage":"http://www.appblog.cn"}
{"name":"Joe.Ye","age":28,"homepage":"http://www.appblog.cn"}
{"name":"Joe.Ye","email":"yezhou@yezhou.org","homepage":"http://www.appblog.cn"}
{"name":"Joe.Ye@AppBlog.CN","email":"yezhou@yezhou.org","age":18,"homepage":"http://www.appblog.cn"}
{"name":"Joe.Ye@AppBlog.CN","age":18,"homepage":"http://www.appblog.cn"}
针对每个模板我们执行一次搜索请求,如果我们工作中针对同一模板可能会有不止一次的请求,如果每个请求都去单独执行的话未免有点繁琐。我们可以通过multiTemplateSearch
实现一次请求实现多条搜索,示例如下:
@GetMapping("template/multiSearch")
public void multiTemplateSearch() {
String[] searchTerms = {"Joe.Ye", "Xiong"}; // 要搜索的条件
MultiSearchTemplateRequest multiRequest = new MultiSearchTemplateRequest();
for (String searchTerm : searchTerms) {
SearchTemplateRequest request = new SearchTemplateRequest();
request.setRequest(new SearchRequest("person")); //指定为person索引库
request.setScriptType(ScriptType.INLINE);
request.setScript(
"{\n" +
" \"query\":{\n" +
" \"match\":{\n" +
" \"{{key}}\":\"{{value}}\"\n" +
" }\n" +
" },\n" +
" \"size\":\"{{size}}\"\n" +
"}");
Map<String, Object> scriptParams = new HashMap<>();
//向模板中填充对应值
scriptParams.put("key", "name");
scriptParams.put("value", searchTerm);
scriptParams.put("size", 5);
request.setScriptParams(scriptParams);
multiRequest.add(request);
}
//执行查询
try {
MultiSearchTemplateResponse multiResponse = client.msearchTemplate(multiRequest, RequestOptions.DEFAULT);
//返回一组响应,每个请求对应一个响应
for (MultiSearchTemplateResponse.Item item : multiResponse.getResponses()) {
if (item.isFailure()) {
String error = item.getFailureMessage(); //搜索请求失败返回错误信息
log.info(error);
} else {
SearchTemplateResponse searchTemplateResponse = item.getResponse();
SearchResponse response = searchTemplateResponse.getResponse();
SearchHits hits = response.getHits();
for (SearchHit hit : hits) {
log.info(hit.getSourceAsString());
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
{"age":28,"height":175.2,"name":"Joe.Ye"}
{"age":26,"height":165.5,"name":"Xiong"}
版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/19/elasticsearch-high-level-rest-api-using-template-search/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论