直接上代码
package cn.itcast.haoke.dubbo.api.service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.codec.binary.StringUtils;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
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 cn.itcast.haoke.dubbo.api.vo.HouseData;
import cn.itcast.haoke.dubbo.api.vo.SearchResult;
@Service
public class SearchService {
@Autowired
private ElasticsearchRestTemplate elasticsearchTemplate;
public static final Integer ROWS = 10;
public SearchResult search(String keyWord, Integer page) {
List<HouseData> houseList = new ArrayList();
Pageable pageable = PageRequest.of(page - 1, ROWS); // 设置分页参数
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery("title", keyWord).operator(Operator.AND)) // match查询
.withPageable(pageable).withHighlightBuilder(getHighlightBuilder("title")) // 设置高亮
.build();
SearchHits<HouseData> searchHits = this.elasticsearchTemplate.search(searchQuery, HouseData.class);
// List<SearchHit<HouseData>> list = housePage.getSearchHits();
for (SearchHit<HouseData> searchHit : searchHits) { // 获取搜索到的数据
HouseData content = (HouseData) searchHit.getContent();
HouseData houseData = new HouseData();
BeanUtils.copyProperties(content, houseData);
// 处理高亮
Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
for (Entry<String, List<String>> stringHighlightFieldEntry : highlightFields.entrySet()) {
String key = stringHighlightFieldEntry.getKey();
if (StringUtils.equals(key, "title")) {
List<String> fragments = stringHighlightFieldEntry.getValue();
StringBuilder sb = new StringBuilder();
for (String fragment : fragments) {
sb.append(fragment.toString());
}
houseData.setTitle(sb.toString());
}
}
houseList.add(houseData);
}
return new SearchResult(((Long) (searchHits.getTotalHits())).intValue(), houseList);
}
// 设置高亮字段
private HighlightBuilder getHighlightBuilder(String... fields) {
// 高亮条件
HighlightBuilder highlightBuilder = new HighlightBuilder(); // 生成高亮查询器
for (String field : fields) {
highlightBuilder.field(field);// 高亮查询字段
}
highlightBuilder.requireFieldMatch(false); // 如果要多个字段高亮,这项要为false
highlightBuilder.preTags("<span style=\"color:red\">"); // 高亮设置
highlightBuilder.postTags("</span>");
// 下面这两项,如果你要高亮如文字内容等有很多字的字段,必须配置,不然会导致高亮不全,文章内容缺失等
highlightBuilder.fragmentSize(800000); // 最大高亮分片数
highlightBuilder.numOfFragments(0); // 从第一个分片获取高亮片段
return highlightBuilder;
}
}
运行:
测试结果:
{
totalPage: 4
list: [4]
0: {
id: "8LwCJ3YBLbVdbvP6qrmw"
title: "整租·<span style="color:red">绿地</span>诺丁山(公寓) 1室1厅 南"
rent: "4500"
floor: "中楼层/11层"
image: "SH2042737281873485824.jpg"
orientation: "55㎡"
houseType: "房屋类型:1室1厅1卫"
rentMethod: "租赁方式:整租"
time: null
}-
1: {
id: "tLwCJ3YBLbVdbvP6qrmv"
title: "整租·<span style="color:red">绿地</span>香颂(奉贤)(别墅) 4室2厅 南"
rent: "7000"
floor: "低楼层/3层"
image: "SH2136087392656818176.jpg"
orientation: "219㎡"
houseType: "房屋类型:4室2厅3卫"
rentMethod: "租赁方式:整租"
time: null
}-
2: {
id: "2LwCJ3YBLbVdbvP6qrmv"
title: "整租·<span style="color:red">绿地</span>香颂(奉贤)(别墅) 4室2厅 南"
rent: "3000"
floor: "低楼层/3层"
image: "SH2280901565906952192.jpg"
orientation: "219㎡"
houseType: "房屋类型:4室2厅3卫"
rentMethod: "租赁方式:整租"
time: null
}-
3: {
id: "vrwCJ3YBLbVdbvP6qrmv"
title: "整租·<span style="color:red">绿地</span>海珀佘山 4室3厅 南/北"
rent: "10000"
floor: "低楼层/2层"
image: "SH2132634396648275968.jpg"
orientation: "380㎡"
houseType: "房屋类型:4室3厅2卫"
rentMethod: "租赁方式:整租"
time: null
}-
-
}
页面修改 添加dangerouslySetInnerHTML :
原来:<Item.Header>
{item.title}
</Item.Header>
改成后:
<Item.Header> </Item.Header>
显示效果: