一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情。
前言
在第5天的更文活动中,我们已经完成了使用kibana调用es的query进行常见的电商场景下的ik分词搜索。今天,我们将在spring boot项目中整合昨天实践的成果
定义高亮标识
我们想要实现搜索结果高亮,首先要把对应的结果加上固定的标识,使它能够在渲染的时候识别出来要高亮显示。我们先固定写死一个高亮显示的响应体,对应的接口定义如下
@RestController
@RequestMapping("es/search")
public class EsSearchController {
@GetMapping("html")
public void html(HttpServletResponse response) throws IOException {
response.setHeader("Content-Type", "text/html; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print(
"<html><body>" +
"颜色是<span class='red'>红色</span>" +
"</body>" +
"<style> .red{color:red }</style>" +
"</html>");
writer.flush();
writer.close();
}
}
复制代码
我们启动项目(没有搭建项目的可以下载我的项目:gitee.com/liangminghu… 访问ip:port/es/search/html,即可显示如下的效果
如何在es中设置高亮标识
想在es中设置响应高亮标识,我们需要使用highlight标签,我们以搜索“华为手机001为例”,按照sort默认升序,我们在kibana中的请求如下
post goods/_search
{
"query": {
"bool": {
"should": [{
"match": {
"name": "华为手机001"
}
},
{
"match": {
"keyWords": "华为手机001"
}
}
]
}
},
"highlight": {
"pre_tags": ["<span class='red'>"],
"post_tags": ["</span>"],
"fields": {
"name": {},
"keyWords": {}
}
},
"from": 0,
"size": 2,
"sort": {
"sort": "asc"
}
}
复制代码
关于query等标签我们已经在上一篇文章解释过了,这里主要介绍一下highlight里的标签
- pre_tags+post_tags:这两个标签定义了分割出的结果以什么tag包围起来,和我们前端的<></>效果差不多
- fields:定义要高亮搜索的属性,name代表名称要高亮,keyWords代表关键词要高亮\
注意:我们在创建索引的时候设置为ik搜索分词了,如果大家默认创建索引会走es的标注分词
使用spring boot整合我们的搜索
一开始我以为要整合es搜索到ik很难,知道我发现了8.1.2的client支持基于json封装请求体,瞬间感觉真香,以下的代码思路来自于官方文档:es官方文档,应该是最简单的集成es搜索的方法了
@GetMapping("doSearch")
public void doSearch(HttpServletResponse response, @RequestParam(value = "word") String word, @RequestParam(value = "sort", defaultValue = "sort") String sort) throws IOException {
if (StringUtils.isBlank(word)) {
return;
}
response.setHeader("Content-Type", "text/html; charset=utf-8");
//初始化estClient
RestClient restClient = RestClient.builder(
new HttpHost("127.0.0.1", 9200, "http")).build();
//设置请求方式和地址
Request request = new Request(
"POST",
"goods/_search");
//基于json构造查询
request.setJsonEntity("{\"query\":{\"bool\":{\"should\":" +
"[{\"match\":{\"name\":\"" + word + "\"}}," +
"{\"match\":{\"keyWords\":\"" + word + "\"}}]}}," +
"\"highlight\":{\"pre_tags\":[\"<span class='red'>\"]" +
",\"post_tags\":[\"</span>\"],\"fields\":{\"name\":{}," +
"\"keyWords\":{}}},\"from\":0,\"size\":5,\"sort\":{\"sort\":\"asc\"}}");
Response esRes = restClient.performRequest(request);
log.info("{}", esRes);
RequestLine requestLine = esRes.getRequestLine();
HttpHost host = esRes.getHost();
int statusCode = esRes.getStatusLine().getStatusCode();
Header[] headers = esRes.getHeaders();
String responseBody = EntityUtils.toString(esRes.getEntity());
##### log.info("{}{}{}{}{}", requestLine, host, statusCode, headers, responseBody);
restClient.close();
PrintWriter writer = response.getWriter();
writer.print(
"<html><body>" +
responseBody +
"</body>" +
"<style> .red{color:red }</style>" +
"</html>");
writer.flush();
writer.close();
}
复制代码
注意这里的client需要关闭,我们分别访问以下地址的得到的结果如下
可以看到name和keyWords都命中了 2. 搜搜麒麟:http://127.0.0.1:4001/es/search/doSearch?word=麒麟
可以看到只命中了我们的关键词
综上我们已经完成了spring boot 集成 es8.1.2 ik分词高亮搜索。关于es的相关探索我们用了6天,希望大家在这6天中能有所收获
结语7
到今天,我们es相关的文章暂时告一段落了,从下期文章开始,我会从大数据方面或者taro多端开发实践中选择一个方向开始更文。欢迎大家多多点赞支持!\