上一篇:
elasticsearch新建索引、mapping映射
一、项目中集成elasticsearch插件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
二、配置服务器ip
三、发起搜索请求
/**
* 分词查询
* @param q
* @return
* @throws Exception
*/
@RequestMapping("/search")
public ModelAndView search(@RequestParam(value="q",required = false)String q, @RequestParam(value = "page",required = false)String page)throws Exception{
ModelAndView mav=new ModelAndView();
if(StringUtil.isEmpty(q)){
mav.setViewName("index");
mav.addObject("title","首页");
return mav;
}
int pageSize=10;
if(StringUtil.isEmpty(page)){
page="1";
}
mav.addObject("q",q);
List<ArticleInfo> articleInfoList = articleService.search(Integer.parseInt(page), pageSize, q);
Long total = articleService.searchCount(q);
mav.addObject("articleInfoList",articleInfoList);
mav.addObject("total",total);
mav.addObject("title",q);
mav.addObject("modelName",q+" - 搜索结果");
mav.addObject("pageCode", PageUtil.genSearchPagination("/search",total,Integer.parseInt(page),pageSize,q));
mav.setViewName("result");
return mav;
}
四、分词检索:
/*
返回的文档可能满足should子句的条件。
在一个Bool查询中,如果没有must或者filter,
有一个或者多个should子句,那么只要满足一个就可以返回
*/
@Override
public List<ArticleInfo> search(Integer page, Integer pageSize, String searchContent) {
PageRequest pageRequest = PageRequest.of(page - 1, pageSize);
//BoolQueryBuilder:拼装连接(查询)条件
// QueryBuilders:查询条件(关系)
BoolQueryBuilder boolQueryBuilder= QueryBuilders.boolQuery()
.should(QueryBuilders.matchQuery("name",searchContent))
.should(QueryBuilders.matchQuery("content",searchContent));
//NativeSearchQueryBuilder:将连接条件和聚合函数等组合
NativeSearchQuery nativeSearchQuery=new NativeSearchQueryBuilder()
.withQuery(boolQueryBuilder)
.withPageable(pageRequest)
.withIndices("test2") //设置索引
.withHighlightFields(new HighlightBuilder.Field("content"),new HighlightBuilder.Field("name"))
.withHighlightBuilder(new HighlightBuilder().preTags("<font style='color:red'>").postTags("</font>")).build();
//查询 并对获取到的数据进行处理、加工
AggregatedPage<ArticleInfo> articleInfos = elasticsearchTemplate.queryForPage(nativeSearchQuery, ArticleInfo.class, new SearchResultMapper() {
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
ArrayList<ArticleInfo> articleInfos = new ArrayList<>();
SearchHits hits = searchResponse.getHits(); //这便是获取到查询数据了
for (SearchHit hit : hits) {
if (hits.getHits().length <= 0) {
return null; //没有数据 结束
}
Map<String, Object> sourceAsMap = hit.getSourceAsMap();//把结果作为一个map返回
// 根据map获取具体数据
String name = (String) sourceAsMap.get("name");
String content = (String) sourceAsMap.get("content");
String id = (String) sourceAsMap.get("id");
System.out.println("name:" + name);
System.out.println("content:" + content);
// 赋值给实体
ArticleInfo articleInfo = new ArticleInfo();
articleInfo.setId(Long.valueOf(id));
HighlightField contentHighlightField = hit.getHighlightFields().get("content");
if (contentHighlightField == null) {
articleInfo.setContent(content);//未查到高亮内容 设置非高亮的
} else {
//可能获取多个片段 这里只取第一个片段 因为bestFragment暂时不知道怎么获取
String highlightContent = hit.getHighlightFields().get("content").fragments()[0].toString();
// 去掉一些 换行符啊什么的
articleInfo.setContent(highlightContent.replaceAll("br", "").replaceAll(" ", "").replaceAll("_", ""));
}
HighlightField nameHighlightField = hit.getHighlightFields().get("name");
if (nameHighlightField == null) {
articleInfo.setName(name);
} else {
articleInfo.setName(hit.getHighlightFields().get("name").fragments()[0].toString());
}
articleInfos.add(articleInfo); //实体封装进集合里面
}
//作为一个集合 这里强转一下
if (articleInfos.size() > 0) {
return new AggregatedPageImpl<T>((List<T>) articleInfos);
}
return null;
}
});
return articleInfos==null?null:articleInfos.getContent();
}
@Override
public Long searchCount(String searchContent) {
BoolQueryBuilder boolQueryBuilder= QueryBuilders.boolQuery()
.should(QueryBuilders.matchQuery("name",searchContent))
.should(QueryBuilders.matchQuery("content",searchContent));
NativeSearchQuery nativeSearchQuery=new NativeSearchQueryBuilder()
.withQuery(boolQueryBuilder)
.withIndices("test2").build();
return elasticsearchTemplate.count(nativeSearchQuery);
}
最终搜索结果如图: