ElasticSearch High Level REST API(5)使用模板搜索

ElasticSearch Rest高级API 提供了多种搜索方式,除了前面讲到的search查询,ElasticSearch 还提供了通过模板搜索查询。

我们可以通过脚本预选注册模板,在注册模板时定义一个模板名称。在查询时通过模板名称调用该模板。

注册模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@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 "";
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
{
"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去调用,动态的将查询参数添加到模板中去。模板调用示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@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();
}
}
1
2
3
4
5
{"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实现一次请求实现多条搜索,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@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();
}
}
1
2
{"age":28,"height":175.2,"name":"Joe.Ye"}
{"age":26,"height":165.5,"name":"Xiong"}

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :