Day414&415&416.检索服务 -谷粒商城

Posted 阿昌喜欢吃黄桃

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Day414&415&416.检索服务 -谷粒商城相关的知识,希望对你有一定的参考价值。

检索服务

0、准备环境

achangmall-search

  • 引入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
</dependency>
  • 配置
spring:
  thymeleaf:
    cache: false
  • 放入页面

  • 在index.html整合thymeleaf
<html lang="en" xmlns:th="http:/www.thymeleaf.org">
  • 将静态资源放入nginx中,创建search文件夹

  • 在index.html修改路径加上/static/search/

  • 配置window转发:C:\\Windows\\System32\\drivers\\etc\\hosts

  • 阿昌项目启动报错:redisson io.netty.channel.epoll.EpollEventLoopGroup

解决方案:移除之前redisson配置文件中的

config.setTransportMode(TransportMode.EPOLL);
  • 配置nginx转发这search服务

  • 配置gateway,转发到search服务
        - id: nginx_route
          uri: lb://achangmall-product
          predicates:
            - Host=achangmall.com

        - id: search_route
          uri: lb://achangmall-search
          predicates:
            - Host=search.achangmall.com
  • 整体的流程

请求search.achangmall.com被nginx转发给gateway转发给search服务

  • 重启各个服务,测试访问search.achangmall.com,是否会被2次转发到search服务

成功!!!!

  • 修改html.html为list.html

  • 页面跳转的控制器com.achang.achangmall.search.controller.SearchController
@Controller
public class SearchController {

    @GetMapping("/list.html")
    public String listPage(){
        return "list";
    }
}
  • 修改achangmall-product/src/main/resources/templates/index.html

  • 修改/mydata/nginx/html/static/index/js/catalogLoader.js

跳转域名修改为你设置的域名

  • 测试搜索框搜索,是否跳转,成功

一、检索

检索参数VO与url

  • 全文检索:skuTitle-》keyword
  • 排序:saleCount(销量)、hotScore(热度分)、skuPrice(价格)
  • 过滤:hasStock、skuPrice区间、brandId、catalog3Id、attrs
  • 聚合:attrs
keyword=小米&
sort=saleCount_desc/asc&
hasStock=0/1&
skuPrice=400_1900&
brandId=1&
catalog3Id=1&
attrs=1_3G:4G:5G&
attrs=2_骁龙845&
attrs=4_高清屏
  • 创建SearchParam用于检索VO
//页面检索条件
@Data
public class SearchParam {
    private String keyword;//全文匹配关键字
    private Long catalog3Id;//三级分类id
    /**
     * sort=saleCount_asc/desc
     * sort=skuPrice_asc/desc
     * sort=hotScore_asc/desc
     */
    private String sort;//排序条件
    private Integer hasStock;//是否只显示有货
    private String skuPrice;//加个区间查询
    private List<Long> brandId;//品牌id,可多选
    private List<String> attrs;//按照属性筛选
    private Integer pageNum = 1;//页码
}

检索结果VO

查询得到商品、总记录数、总页码

品牌list用于在品牌栏显示,分类list用于在分类栏显示

其他栏每栏用AttrVo表示

不仅要根据关键字从es中检索到商品

还要通过聚合生成品牌等信息,方便分类栏显示

  • 检索结果VO
//检索返回页面Bean
@Data
public class SearchResult {
    private List<SkuEsModel> products;//ES数据结构查询到的商品信息

    private Integer pageNum;//当前页码
    private Long total;//总记录数
    private Integer totalPage;//总页码

    private List<BrandVo> brandVos;//当前查询涉及到的品牌信息
    private List<AttrVo> attrVos;//当前查询涉及到的属性信息
    private List<CatalogVo> catalogVos;//当前查询涉及到的分类信息


    //=========以上返给页面的信息=============

    //品牌vo对象
    public static class BrandVo{
        private Integer brandId;
        private String brandName;
        private String brandImg;
    }

    //分类vo对象
    public static class CatalogVo{
        private Integer catalogId;
        private String catalogName;
    }

    //属性vo对象
    public static class AttrVo{
        private Integer attrId;
        private String attrName;
        private List<String> attrValues;
    }
}
  • com.achang.achangmall.search.controller.SearchController
@Controller
public class SearchController {

    @Autowired
    MallSearchService mallSearchService;

    @GetMapping("/list.html")
    public String listPage(SearchParam param, Model model ){
        SearchResult result = mallSearchService.search(param);
        model.addAttribute("result",result);
        return "list";
    }
}
  • com.achang.achangmall.search.service.impl.MallSearchServiceImpl
package com.achang.achangmall.search.service.impl;

import com.achang.achangmall.search.conf.ElasticsearchConfig;
import com.achang.achangmall.search.constant.ESConstant;
import com.achang.achangmall.search.service.MallSearchService;
import com.achang.achangmall.search.vo.SearchParam;
import com.achang.achangmall.search.vo.SearchResult;
import com.achang.common.to.es.SkuEsModel;
import com.alibaba.fastjson.JSON;
import org.apache.lucene.search.join.ScoreMode;
import org.apache.lucene.util.QueryBuilder;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.NestedQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.nested.ParsedNested;
import org.elasticsearch.search.aggregations.bucket.terms.*;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.swing.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/******
 @author 阿昌
 @create 2021-10-08 21:55
 *******
 */
@Service
public class MallSearchServiceImpl implements MallSearchService {

    @Resource
    private RestHighLevelClient client;

    @Override
    public SearchResult search(SearchParam param) {
        SearchResult result = null;
        SearchRequest request = buildSearchRequest(param);

        try {
            SearchResponse response = client.search(request, ElasticsearchConfig.COMMON_OPTIONS);

            result = buildSearchResult(response,param);
        } catch (IOException e) {
            e.printStackTrace();
        }


        return result;
    }

    //构建结果数据
    private SearchResult buildSearchResult(SearchResponse response,SearchParam param) {
        SearchResult result = new SearchResult();
        SearchHits hits = response.getHits();
        SearchHit[] hitsHits = hits.getHits();//命中数据
        //查询到的所有商品
        List<SkuEsModel> products = new ArrayList<>(hitsHits.length);
        if (!StringUtils.isEmpty(hitsHits)&&hitsHits.length>0){
            for (SearchHit hitsHit : hitsHits) {
                String sourceAsString = hitsHit.getSourceAsString();
                SkuEsModel skuEsModel = JSON.parseObject(sourceAsString, SkuEsModel.class);
                HighlightField skuTitle = hitsHit.getHighlightFields().get("skuTitle");
                if (!StringUtils.isEmpty(param.getKeyword())){
                    skuEsModel.setSkuTitle(skuTitle.getFragments()[0].toString());//设置高亮text
                }
                products.add(skuEsModel);
            }
        }
        result.setProducts(products);


        //商品所涉及到的所有属性信息
        ParsedLongTerms catalog_agg = response.getAggregations().get("catalog_agg");
        List<? extends Terms.Bucket> buckets = catalog_agg.getBuckets();
        List<SearchResult.CatalogVo> catalogVos = new ArrayList<>(buckets.size());
        for (Terms.Bucket bucket : buckets) {
            SearchResult.CatalogVo catalogVo = new SearchResult.CatalogVo();
            ParsedStringTerms catalog_name_agg = bucket.getAggregations().get("catalog_name_agg");

            catalogVo.setCatalogName(catalog_name_agg.getBuckets().get(0).getKeyAsString());
            catalogVo.setCatalogId((int) Long.parseLong(bucket.getKeyAsString()));
            catalogVos.add(catalogVo);
        }
        result.setCatalogVos(catalogVos);

        //商品所涉及到所有的品牌信息
        ParsedLongTerms brand_agg = response.getAggregations().get("brand_agg");
        List<? extends Terms.Bucket> brandAggBuckets = brand_agg.getBuckets();
        List<SearchResult.BrandVo> brandVos = new ArrayList<>(brandAggBuckets.size());
        for (Terms.Bucket brandAggBucket : brandAggBuckets) {
            SearchResult.BrandVo brandVo = new SearchResult.BrandVo();
            ParsedStringTerms brand_img_agg = brandAggBucket.getAggregations().get("brand_img_agg");
            ParsedStringTerms brand_name_agg = brandAggBucket.getAggregations().get("brand_name_agg");

            brandVo.setBrandName(brand_name_agg.getBuckets().get(0).getKeyAsString());
            brandVo.setBrandImg(brand_img_agg.getBuckets().get(0).getKeyAsString());
            brandVo.setBrandId((int) brandAggBucket.getKeyAsNumber().longValue());
            brandVos.add(brandVo);
        }
        result.setBrandVos(brandVos);

        //当前商品所及到所有的属性信息
        ParsedNested attr_agg = response.getAggregations().get("attr_agg");
        ParsedLongTerms attr_id_agg = attr_agg.getAggregations().get("attr_id_agg");
        List<? extends Terms.Bucket> attrIdAggBuckets = attr_id_agg.getBuckets();
        List<SearchResult.AttrVo> attrVos = new ArrayList<>(attrIdAggBuckets.size());
        for (Terms.Bucket attrIdAggBucket : attrIdAggBuckets) {
            SearchResult.AttrVo attrVo = new SearchResult.AttrVo();
            int id = attrIdAggBucket.getKeyAsNumber().intValue();
            ParsedStringTerms attr_name_agg = attrIdAggBucket.getAggregations().get("attr_name_agg");
            String attrName = attr_name_agg.getBuckets().get(0).getKeyAsString();
            ParsedStringTerms attr_value_agg = attrIdAggBucket.getAggregations().get("attr_value_agg");
            List<? extends Terms.Bucket> value_aggBuckets = attr_value_agg.getBuckets();

            ArrayList<String> attrValueList = new <

以上是关于Day414&415&416.检索服务 -谷粒商城的主要内容,如果未能解决你的问题,请参考以下文章

nginx415错误

javaSE第二十六天

Day407&408&409.ES -谷粒商城

史航416第11次作业&总结

史航416附加题

UVa 414 - Machined Surfaces