本文只针对SpringBoot集成spring-boot-starter-data-elasticsearch 或者Spring-data-elasticsearch实现分页和高亮。
由于最近对es做高亮显示,发现查到的大多是都是使用ElasticsearchRestTemplate.queryForPage()或者ElasticsearchTemplate.queryForPage()方法实现。这两个方法都已不建议使用
且尝试多次均未能达到高亮效果。这才有此总结。
经测试:spring-boot-starter-data-elasticsearch的版本从2.0.0至目前的2.4.x都是支持的
Spring-data-elasticsearch版本4.0.0至目前的4.1.x也都是支持的
实现如下:
1:引入maven坐标
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>4.1.5</version>
</dependency>
或者:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>2.4.3</version>
</dependency>
2:配置
spring:
data:
elasticsearch:
client:
reactive:
endpoints: 192.168.100.181:9200
elasticsearch:
rest:
uris: 192.168.100.181:9200
# 下面的这两个属性在新版本的springboot中已经不建议使用,9300属于elasticsearch各节点之间的通讯接口。 属于lowlevelclient。推荐使用9200的RestHighLevelClient去链接
# cluster-nodes: 192.168.100.181:9300
# cluster-name: helloElasticsearch
3:代码实现
/**
注:Message 实体类
MessageService接口
DateTimeUtil 时间工具类
MessageVo 接受的参数
*/
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @Date: 2021/3/4
*/
@Service
public class MessageServiceImpl implements MessageService {
@Autowired
ElasticsearchRestTemplate elasticsearchRestTemplate;
/** 根据ID查询 */
@Override
public Message getMessageById(String id) {
//IndexCoordinates.of("ddc-log") 可以指定查询索引
Message message = elasticsearchRestTemplate.get(id, Message.class);
return message;
}
/** 根据Key查询并分页高亮显示 */
@Override
public Page getMessageList(MessageVo messageVo) {
NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
//布尔查询
BoolQueryBuilder bool = QueryBuilders.boolQuery();
if(!StringUtils.isEmpty(messageVo.getKey())){
// 构建高亮查询
HighlightBuilder.Field field = new HighlightBuilder.Field("message").preTags("<font style='color:red'>").postTags("</font>");
builder.withHighlightFields(field);
bool.must(QueryBuilders.matchPhraseQuery("message", messageVo.getKey()));
}
//时间范围过滤
if(!StringUtils.isEmpty(messageVo.getStartTime()) && !StringUtils.isEmpty(messageVo.getEndTime())){
RangeQueryBuilder range = QueryBuilders.rangeQuery("@timestamp");
range.from(DateTimeUtil.getLongTimeByStringDefault(messageVo.getStartTime())).to(DateTimeUtil.getLongTimeByStringDefault(messageVo.getEndTime()));
List<QueryBuilder> filter = bool.filter();
filter.add(range);
}
builder.withQuery(bool);
//排序 仅支持对时间倒序和正序排序
if("asc".equals(messageVo.getOrderType())){
builder.withSort(SortBuilders.fieldSort("@timestamp").order(SortOrder.ASC));
}else{
builder.withSort(SortBuilders.fieldSort("@timestamp").order(SortOrder.DESC));
}
//分页
PageRequest pageRequest = PageRequest.of(messageVo.getCurrPage(), messageVo.getPageSize());
builder.withPageable(pageRequest);
//构造查询条件
NativeSearchQuery query = builder.build();
//执行查询 //IndexCoordinates.of("ddc-log")
SearchHits<Message> hits=elasticsearchRestTemplate.search(query, Message.class);
//创建list对象
List<Message> messageList=new ArrayList<>();
hits.forEach(item -> {
Message content = item.getContent();
//获取高亮信息
List<String> filename=item.getHighlightField("message");
if(filename.size()>0) {
//替换原来字段内容
content.setMessage(filename.get(0));
}
messageList.add(content);
});
// 组装分页对象
Page<Message> page = new PageImpl<>(messageList,pageRequest,hits.getTotalHits());
return page;
}
}
/**
* 指定字符(yyyy-MM-dd HH:mm:ss)转换成时间戳
*
* @param dateStr
* @return
*/
public static Long getLongTimeByStringDefault(String dateStr) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date date = simpleDateFormat.parse(dateStr);
long ts = date.getTime();
return ts;
} catch (Exception e) {
return 0L;
}
}
至此,除根据自己项目修改部分字段名称外,可直接copy使用