| 
1.2 实现思路 (1)后端使用匹配查询和布尔查询 (2)前端使用thymeleaf模板渲染 (3)前端向后端传递map(因为提交的不仅仅是关键字,还有品牌、规格、分类等信息) (4)后端向前端返回map(因为返回的不仅仅是列表,还有商品分类、品牌和规格列表等数据) 1.3 代码实现1.3.1 集成elasticsearch高级客户端(1)qingcheng_service_goods工程pom.xml新增依赖 <dependency> 
    <groupId>org.elasticsearch.client</groupId> 
    <artifactId>elasticsearch-rest-high-level-client</artifactId> 
    <version>6.5.3</version> 
</dependency>(2)qingcheng_service_goods工程新增工厂类 public class RestClientFactory { 
         
    public static RestHighLevelClient getRestHighLevelClient(String hostname,int port){ 
        HttpHost http=new HttpHost(hostname,port,"http"); 
        RestClientBuilder builder= RestClient.builder(http);//rest构建器 
        return new RestHighLevelClient(builder);//高级客户端对象 (连接)         
    }     
}(3)qingcheng_service_goods工程applicationContext-service.xml新增配置     <!--es client--> 
    <bean id="restHighLevelClient" class="com.qingcheng.service.impl.RestClientFactory" factory-method="getRestHighLevelClient"> 
        <constructor-arg index="0" value="127.0.0.1"></constructor-arg> 
        <constructor-arg index="1" value="9200"></constructor-arg> 
    </bean>1.3.2 关键字搜索逻辑(1)qingcheng_interface工程新增接口  SkuSearchService  服务接口新增方法定义 public interface SkuSearchService { 
 
    public Map search(Map<String,String> searchMap); 
 
}(2)qingcheng_service_goods工程新增服务实现类SkuSearchServiceImpl  实现此方法,实现关键字查询 @Service 
public class SkuSearchServiceImpl implements SkuSearchService { 
 
    @Autowired 
    private RestHighLevelClient restHighLevelClient; 
 
    public Map search(Map<String,String> searchMap) { 
 
        //1.封装查询请求 
        SearchRequest searchRequest=new SearchRequest("sku"); 
        searchRequest.types("doc"); //设置查询的类型 
 
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder(); 
 
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//布尔查询构建器 
 
        //1.1 关键字搜索 
        if(searchMap.get("keywords")!=null){ 
            MatchQueryBuilder matchQueryBuilder=    QueryBuilders.matchQuery("name",searchMap.get("keywords")); 
            boolQueryBuilder.must(matchQueryBuilder); 
        } 
 
        searchSourceBuilder.query(boolQueryBuilder); 
        searchRequest.source(searchSourceBuilder); 
 
 
        //2.封装查询结果 
        Map resultMap=new HashMap(); 
        try { 
            SearchResponse searchResponse  = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); 
            SearchHits searchHits = searchResponse.getHits(); 
            long totalHits = searchHits.getTotalHits(); 
            System.out.println("记录数:"+totalHits); 
            SearchHit[] hits = searchHits.getHits(); 
 
            //2.1 商品列表 
            List<Map<String,Object>> resultList=new ArrayList<Map<String, Object>>(); 
            for(SearchHit hit:hits){ 
                Map<String, Object> skuMap = hit.getSourceAsMap(); 
                resultList.add(skuMap); 
            } 
            resultMap.put("rows",resultList); 
 
        } catch (IOException e) { 
            e.printStackTrace(); 
        } 
        return resultMap; 
    } 
 
}(3)qingcheng_web_portal工程新增类 @Controller 
public class SearchController { 
 
    @Reference 
    private SkuSearchService skuSearchService; 
 
    @GetMapping("/search") 
    public String search(Model model, @RequestParam Map<String, String> searchMap) throws Exception { 
        //字符集处理 
        searchMap = WebUtil.convertCharsetToUTF8(searchMap); 
        //远程调用接口 
        Map result = skuSearchService.search(searchMap);         
        model.addAttribute("result", result); 
        return "search"; 
    } 
}WebUtil类是工具类,用于字符集转码,资源中提供 1.3.3 模板构建(1)qingcheng_web_portal工程新增模板,将资源\静态原型\网站前台\search.htm拷贝到WEB-INF下,并进行以下修改 <html xmlns:th="http://www.thymeleaf.org">遍历查询结果 <ul class="yui3-g"> 
    <li class="yui3-u-1-5" th:each="sku:${result.rows}"> 
        <div class="list-wrap"> 
            <div class="p-img"> 
                <a href="item.html" target="_blank"><img th:src="${sku.image}" /></a> 
            </div> 
            <div class="price"> 
                <strong> 
                    <em>¥</em> 
                    <i th:text="${#numbers.formatDecimal(sku.price/100.0,0,2)}"></i> 
                </strong> 
            </div> 
            <div class="attr"> 
                <em th:text="${sku.name}"></em> 
            </div> 
            <div class="operate"> 
                <a href="success-cart.html" target="_blank" class="sui-btn btn-bordered btn-danger">加入购物车</a> 
                <a href="javascript:void(0);" class="sui-btn btn-bordered">收藏</a> 
            </div> 
        </div> 
    </li> 
</ul>测试  浏览器输入 http://localhost:9102/search.do?keywords=手机 (2)修改index.html的关键字搜索表单 <form action="/search.do" class="sui-form form-inline"> 
    <!--searchAutoComplete--> 
    <div class="input-append"> 
        <input type="text" name="keywords" id="autocomplete" class="input-error input-xxlarge" /> 
        <button class="sui-btn btn-xlarge btn-danger" type="submit" >搜索</button> 
    </div> 
</form>修改search.html的关键字搜索表单,内容同上 2. 商品分类过滤2.1 需求分析以关键字作为查询条件,查询结果中包含的商品分类,在页面中显示出来 file://D:/%E5%AD%A6%E4%B9%A0%E7%94%A8/%E9%9D%92%E5%9F%8E%E9%A1%B9%E7%9B%AE/%E8%AE%B2%E4%B9%89/%E9%A1%B9%E7%9B%AE2/%E8%AE%B2%E4%B9%89/img/4-3.png?lastModify=1565765131 点击商品分类,按商品分类对结果进行过滤查询,并且在查询条件列表中添加已经选择的商品分类标签,隐藏搜索面板中的商品分类一行。 点击条件标签的“×”,取消该过滤条件 2.2 实现思路(1)商品分类列表的显示使用聚合查询 (2)使用过滤查询 2.3 代码实现 2.3.1 商品分类列表(1)修改SkuSearchServiceImpl的search方法,在第一段代码(封装查询请求)的末尾处添加以下代码: //聚合查询(商品分类) 
TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("sku_category").field("categoryName"); 
searchSourceBuilder.aggregation(termsAggregationBuilder);   在第二段代码中添加以下代码: //2.2 商品分类列表 
Aggregations aggregations = searchResponse.getAggregations(); 
Map<String, Aggregation> aggregationMap = aggregations.getAsMap(); 
Terms terms = (Terms) aggregationMap.get("sku_category"); 
 
List<? extends Terms.Bucket> buckets =  terms.getBuckets(); 
List<String> categoryList=new ArrayList(); 
for( Terms.Bucket bucket:buckets ){ 
    categoryList.add(bucket.getKeyAsString()); 
} 
resultMap.put("categoryList",categoryList);(2)修改qingcheng_web_portal的search.html   商品分类列表 <div class="type-wrap"> 
    <div class="fl key">商品分类</div> 
    <div class="fl value" th:each="category:${result.categoryList}"> 
        <span> 
             <a href="javascript:void(0)" th:utext="${category+' '} " ></a> 
         </span> 
    </div> 
    <div class="fl ext"></div> 
</div>2.3.2 分类过滤查询 
 |