接下来处理模糊查询功能
- 匹配查询
修改controller代码,如果传入的keyword不是空值,则改为使用匹配查询
@RequestMapping("/blogs")
public String query(Model model, String keyword, Integer pageNum, Integer pageSize) {
if(pageNum == null || pageNum <= 0)
pageNum = 1;
if(pageSize == null || pageSize <= 0)
pageSize = 5;
SearchQuery searchQuery = null;
if (StringUtils.isNotBlank(keyword)) {
searchQuery = new NativeSearchQueryBuilder()
.withPageable(new QPageRequest(pageNum - 1, pageSize))
.withQuery(QueryBuilders.multiMatchQuery(keyword, "text", "author"))
.withSort(SortBuilders.fieldSort("date").order(SortOrder.DESC))
.build();
} else {
searchQuery = new NativeSearchQueryBuilder()
.withPageable(new QPageRequest(pageNum - 1, pageSize))
.withQuery(QueryBuilders.matchAllQuery())
.withSort(SortBuilders.fieldSort("date").order(SortOrder.DESC))
.build();
}
Page<Blog> blogs = elasticsearchTemplate.queryForPage(searchQuery, Blog.class);
model.addAttribute("blogs", blogs.getContent());
model.addAttribute("pageHelper", new PageHelper<>(blogs, pageNum, pageSize));
model.addAttribute("keyword", keyword);
return "index";
}
- 高亮显示
spring-data-elasticsearch使用SearchResultMapper接口实现对搜索结果的再加工,搜索结果的高亮显示可以通过该接口的实现类来实现。
import com.alibaba.fastjson.JSON;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class HighlightResultMapper implements SearchResultMapper {
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> clazz, Pageable pageable) {
long totalHits = searchResponse.getHits().getTotalHits();
List<T> list = new ArrayList<>();
SearchHits hits = searchResponse.getHits();
if (hits.getHits().length> 0) {
for (SearchHit searchHit : hits) {
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
T item = JSON.parseObject(searchHit.getSourceAsString(), clazz);
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
if (highlightFields.containsKey(field.getName())) {
try {
field.set(item, highlightFields.get(field.getName()).fragments()[0].toString());
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
list.add(item);
}
}
return new AggregatedPageImpl<>(list, pageable, totalHits);
}
}
对controller代码稍作修改
String authorFieldName = "author";
String textFieldName = "text";
String preTags = "<span style=\"color:#F56C6C\">";
String postTags = "</span>";
HighlightBuilder.Field authorField = new HighlightBuilder.Field(authorFieldName).preTags(preTags).postTags(postTags);
HighlightBuilder.Field textField = new HighlightBuilder.Field(textFieldName).preTags(preTags).postTags(postTags);
SearchQuery searchQuery = null;
if (StringUtils.isNotBlank(keyword)) {
searchQuery = new NativeSearchQueryBuilder()
.withPageable(new QPageRequest(pageNum - 1, pageSize))
.withQuery(QueryBuilders.multiMatchQuery(keyword, "text", "author"))
.withHighlightFields(authorField, textField)
.withSort(SortBuilders.fieldSort("date").order(SortOrder.DESC))
.build();
} else {
searchQuery = new NativeSearchQueryBuilder()
.withPageable(new QPageRequest(pageNum - 1, pageSize))
.withQuery(QueryBuilders.matchAllQuery())
.withSort(SortBuilders.fieldSort("date").order(SortOrder.DESC))
.build();
}
Page<Blog> blogs = elasticsearchTemplate.queryForPage(searchQuery, Blog.class, new HighlightResultMapper());
效果
代码
链接:https://pan.baidu.com/s/13pAWNl_KLQg4RdAClYH9Rg
提取码:qm0l