成都企業(yè)網(wǎng)站維護專業(yè)外貿(mào)網(wǎng)絡(luò)推廣
一、 高亮顯示
1.1 高亮分析
高亮顯示是指根據(jù)商品關(guān)鍵字搜索商品的時候,顯示的頁面對關(guān)鍵字給定了特殊樣式,讓它顯示更加突出,如商品搜索中,關(guān)鍵字變成了紅色,其實就是給定了紅色樣式。
1.2 高亮搜索實現(xiàn)步驟解析
將之前的搜索換掉,換成高亮搜索,我們需要做3個步驟:
1.指定高亮域,也就是設(shè)置哪個域需要高亮顯示設(shè)置高亮域的時候,需要指定前綴和后綴,也就是關(guān)鍵詞用什么html標簽包裹,再給該標簽樣式
2.高亮搜索實現(xiàn)
3.將非高亮數(shù)據(jù)替換成高亮數(shù)據(jù)
第1點,例如在百度中搜索數(shù)據(jù)的時候,會有2個地方高亮顯示,分別是標題和描述,商城搜索的時候,只是商品名稱高亮顯示了。而高亮顯示其實就是添加了樣式,例如手機,而其中span開始標簽可以稱為前綴,span結(jié)束標簽可以稱為后綴。
第2點,高亮搜索使用ElasticsearchTemplate實現(xiàn)。
第3點,高亮搜索后,會搜出非高亮數(shù)據(jù)和高亮數(shù)據(jù),高亮數(shù)據(jù)會加上第1點中的高亮樣式,此時我們需要將非高亮數(shù)據(jù)換成高亮數(shù)據(jù)即可。例如非高亮:華為筆記本性能超強悍 高亮數(shù)據(jù):華為<span style="color:red;"筆記本性能超強悍,將非高亮的換成高亮的,到頁面就能顯示樣式了。
1.3 高亮代碼實現(xiàn)
高亮代碼實現(xiàn):
代碼如下:
@Override
public Map search(Map<String, String> searchMap) throws Exception {Map<String, Object> resultMap = new HashMap<>();
?//有條件才查詢Esif (null != searchMap) {//組合條件對象BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();//0:關(guān)鍵詞if (!StringUtils.isEmpty(searchMap.get("keywords"))) {boolQuery.must(QueryBuilders.matchQuery("name", searchMap.get("keywords")).operator(Operator.AND));}//1:條件 品牌if (!StringUtils.isEmpty(searchMap.get("brand"))) {boolQuery.filter(QueryBuilders.termQuery("brandName", searchMap.get("brand")));}
?//2:條件 規(guī)格for (String key : searchMap.keySet()) {if (key.startsWith("spec_")) {String value = searchMap.get(key).replace("%2B", "+");boolQuery.filter(QueryBuilders.termQuery("specMap." + key.substring(5) + ".keyword",value));}}//3:條件 價格if (!StringUtils.isEmpty(searchMap.get("price"))) {String[] p = searchMap.get("price").split("-");boolQuery.filter(QueryBuilders.rangeQuery("price").gte(p[0]));if (p.length == 2) {boolQuery.filter(QueryBuilders.rangeQuery("price").lte(p[1]));}}
?//4. 原生搜索實現(xiàn)類NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();nativeSearchQueryBuilder.withQuery(boolQuery);
?//5:高亮HighlightBuilder.Field field = new HighlightBuilder.Field("name").preTags("<span style='color:red'>").postTags("</span>");nativeSearchQueryBuilder.withHighlightFields(field);
?//6. 品牌聚合(分組)查詢String skuBrand = "skuBrand";nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms(skuBrand).field("brandName"));
?//7. 規(guī)格聚合(分組)查詢String skuSpec = "skuSpec";nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms(skuSpec).field("spec.keyword"));
?//8: 排序if (!StringUtils.isEmpty(searchMap.get("sortField"))) {if ("ASC".equals(searchMap.get("sortRule"))) {nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(searchMap.get("sortField")).order(SortOrder.ASC));} else {
?nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(searchMap.get("sortField")).order(SortOrder.DESC));}
?}
?String pageNum = searchMap.get("pageNum");if (null == pageNum) {pageNum = "1";}//9: 分頁nativeSearchQueryBuilder.withPageable(PageRequest.of(Integer.parseInt(pageNum) - 1, Page.pageSize));
?//10: 執(zhí)行查詢, 返回結(jié)果對象AggregatedPage<SkuInfo> aggregatedPage = esTemplate.queryForPage(nativeSearchQueryBuilder.build(), SkuInfo.class, new SearchResultMapper() {@Overridepublic <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
?List<T> list = new ArrayList<>();
?SearchHits hits = searchResponse.getHits();if (null != hits) {for (SearchHit hit : hits) {SkuInfo skuInfo = JSON.parseObject(hit.getSourceAsString(), SkuInfo.class);
?Map<String, HighlightField> highlightFields = hit.getHighlightFields();if (null != highlightFields && highlightFields.size() > 0) {skuInfo.setName(highlightFields.get("name").getFragments()[0].toString());}list.add((T) skuInfo);}}return new AggregatedPageImpl<T>(list, pageable, hits.getTotalHits(), searchResponse.getAggregations());}});
?//11. 總條數(shù)resultMap.put("total", aggregatedPage.getTotalElements());//12. 總頁數(shù)resultMap.put("totalPages", aggregatedPage.getTotalPages());//13. 查詢結(jié)果集合resultMap.put("rows", aggregatedPage.getContent());
?//14. 獲取品牌聚合結(jié)果StringTerms brandTerms = (StringTerms) aggregatedPage.getAggregation(skuBrand);List<String> brandList = brandTerms.getBuckets().stream().map(bucket -> bucket.getKeyAsString()).collect(Collectors.toList());resultMap.put("brandList", brandList);
?//15. 獲取規(guī)格聚合結(jié)果StringTerms specTerms = (StringTerms) aggregatedPage.getAggregation(skuSpec);List<String> specList = specTerms.getBuckets().stream().map(bucket -> bucket.getKeyAsString()).collect(Collectors.toList());resultMap.put("specList", specList(specList));
?//16. 返回當前頁resultMap.put("pageNum", pageNum);
?return resultMap;}
?return null;
}
?
1.4 測試
測試搜索結(jié)果高亮顯示