學習筆記(11)商品上架與ES檢索

松鶴樓發表於2020-12-05

學習筆記(11)商品上架與ES檢索

商品上架

商品裡有很多SKU:

在這裡插入圖片描述

每個SKU有自己的銷售屬性:
在這裡插入圖片描述

除此之外,每個商品有共用的商品屬性:

在這裡插入圖片描述

檢索出來的介面標題是SPU+SKU都有

查詢商品的詳情

SPU的資訊拿來篩選,SKU的資訊拿來售賣
在這裡插入圖片描述

SELECT pav.*,pa.`name` FROM `pms_product_attribute_value` pav 
	LEFT JOIN `pms_product_attribute` pa
	ON pa.`id` = pav.`product_attribute_id`
WHERE pav.`product_id` =23

上架5號

在這裡插入圖片描述

在這裡插入圖片描述
在這裡插入圖片描述

dubbo叢集容錯

查詢多試驗幾次,增刪改要快速失敗。選擇dubbo的快速失敗模式


在這裡插入圖片描述

dubbo配置預設在服務上,調不精細

CudSerivce:增刪改service
* RService:讀service
*
*1)、dubbo的預設叢集容錯哪幾種,怎麼做?
* failover/failfast/failsafe/failback/forking;
* @Service註解上一配置就行。
目前本系統未按此設計
* 改掉預設的mapping資訊;
* 1)、改掉不分詞的欄位
* 2)、整個info就是ESProduct,//嵌入式物件的Mapping一定要用nested宣告,這樣才能正確的檢索到資料
不分詞用keyword

在這裡插入圖片描述

什麼需要評分:只有在搜尋框搜的關鍵字需要評分

 /**
     * 給資料庫插入資料
     * 1)、dubbo遠端呼叫插入資料服務,可能經常超時。dubbo預設會重試
     * 導致這個方法會被呼叫多次。可能導致資料庫同樣的資料有多個。
     *
     * 2)、dubbo有自己預設的叢集容錯。
     *
     * 給資料庫做資料的,最好用dubbo的快速失敗模式。我們手工重試
     *
     * @param id
     */
    private void saveProductToEs(Long id) {
        //1、查出商品的基本新
        Product productInfo = productInfo(id);
        EsProduct esProduct = new EsProduct();


        //1、複製基本資訊
        BeanUtils.copyProperties(productInfo,esProduct);


        //2、複製sku資訊,對於es要儲存商品資訊,還要查出這個商品的sku,給es中儲存
        List<SkuStock> stocks = skuStockMapper.selectList(new QueryWrapper<SkuStock>().eq("product_id", id));
        List<EsSkuProductInfo> esSkuProductInfos = new ArrayList<>(stocks.size());

 //       List<EsProductAttributeValue> skuAttributeNames = productAttributeValueMapper.selectProductSaleAttrName(id);
//        List<EsProductAttributeValue> attributeValues = productAttributeValueMapper.selectProductBaseAttrAndValue(id);
        //查出當前商品的sku屬性  顏色  尺碼
        List<ProductAttribute>  skuAttributeNames = productAttributeValueMapper.selectProductSaleAttrName(id);
        stocks.forEach((skuStock)->{
            EsSkuProductInfo info = new EsSkuProductInfo();
            BeanUtils.copyProperties(skuStock,info);

            //閃亮 黑色
            String subTitle = esProduct.getName();
            if(!StringUtils.isEmpty(skuStock.getSp1())){
                subTitle+=" "+skuStock.getSp1();
            }
            if(!StringUtils.isEmpty(skuStock.getSp2())){
                subTitle+=" "+skuStock.getSp2();
            }
            if(!StringUtils.isEmpty(skuStock.getSp3())){
                subTitle+=" "+skuStock.getSp3();
            }
            //sku的特色標題
            info.setSkuTitle(subTitle);
            List<EsProductAttributeValue> skuAttributeValues = new ArrayList<>();

            for (int i=0;i<skuAttributeNames.size();i++){
                //skuAttr 顏色/尺碼
                EsProductAttributeValue value = new EsProductAttributeValue();

                value.setName(skuAttributeNames.get(i).getName());
                value.setProductId(id);
                value.setProductAttributeId(skuAttributeNames.get(i).getId());
                value.setType(skuAttributeNames.get(i).getType());

                //顏色   尺碼;讓es去統計‘;改掉查詢商品的屬性分類裡面所有屬性的時候,按照sort欄位排序好
                if(i==0){
                    value.setValue(skuStock.getSp1());
                }
                if(i==1){
                    value.setValue(skuStock.getSp2());
                }
                if(i==2){
                    value.setValue(skuStock.getSp3());
                }

                skuAttributeValues.add(value);

            }


            info.setAttributeValues(skuAttributeValues);
            //sku有多個銷售屬性;顏色,尺碼
            esSkuProductInfos.add(info);
            //查出銷售屬性的名

        });

        esProduct.setSkuProductInfos(esSkuProductInfos);


        List<EsProductAttributeValue> attributeValues = productAttributeValueMapper.selectProductBaseAttrAndValue(id);
        //3、複製公共屬性資訊,查出這個商品的公共屬性
        esProduct.setAttrValueList(attributeValues);

        try {
            //把商品儲存到es中
            Index build = new Index.Builder(esProduct)
                    .index(EsConstant.PRODUCT_ES_INDEX)
                    .type(EsConstant.PRODUCT_INFO_ES_TYPE)
                    .id(id.toString())
                    .build();
            DocumentResult execute = jestClient.execute(build);
            boolean succeeded = execute.isSucceeded();
            if(succeeded){
                log.info("ES中;id為{}商品上架完成",id);
            }else {
                log.error("ES中;id為{}商品未儲存成功,開始重試",id);
                //saveProductToEs(id);
            }
        }catch (Exception e){
            log.error("ES中;id為{}商品資料儲存異常;{}",id,e.getMessage());
            //saveProductToEs(id);
        }

    }

1.對於資料庫是修改商品的狀態位

2.對於es要儲存的商品資訊

mybatis-plus自帶的更新方法是哪個欄位有值就更哪個欄位(所以所有型別應該用包裝類,因為非包裝類有預設值)

我們上架的是SKU(仿京東,一些小的商城系統,比如小米,上架的是SPU,之後自己選)

上下架請求:

在這裡插入圖片描述

對於資料庫是修改商品的狀態位

對於es要儲存商品資訊

商品的屬性分類如下:

在這裡插入圖片描述

SKU有其基本資訊,又有銷售屬性

javaBean應該都去用包裝型別

public void setProductPublishStatus(Integer publishStatus, Long id) {
    //javaBean應該都去用包裝型別
    Product product = new Product();
    //預設所有屬性為null
    product.setId(id);
    product.setPublishStatus(publishStatus);
    //mybatis-plus自帶的更新方法是哪個欄位有值就更哪個欄位
    productMapper.updateById(product);
}

es也會佔用硬碟空間 ,同步

檢索服務

分散式系統下,session不一致,前端第一次請求到達x伺服器上,下回請求來到y伺服器,就取不出來了,session不一致

後端解決session不一致問題麻煩,但是前端解決容易,訪問來訪問去就是瀏覽器。

gmall-shop-portal: 和前端公眾訪問的商品專案進行對接的web

聚合

第一步:分析頁面會傳入哪些引數,可以把所有引數寫成一個javaBean

第二步:要把哪些結果返回去

/**
 * 檢索前端傳遞的資料
 */
@Data
public class SearchParam implements Serializable {
@Data
public class SearchResponse implements Serializable {

    private SearchResponseAttrVo brand;//品牌
    private SearchResponseAttrVo catelog;//分類
    //所有商品的頂頭顯示的篩選屬性
    private List<SearchResponseAttrVo> attrs = new ArrayList<SearchResponseAttrVo>();

    //檢索出來的商品資訊
    private List<EsProduct> products = new ArrayList<EsProduct>();

    private Long total;//總記錄數
    private Integer pageSize;//每頁顯示的內容
    private Integer pageNum;//當前頁面


}

在這裡插入圖片描述

每個 SearchResponseAttrVo相當於上圖的一行

啟動前端專案:npm install

web服務是消費者

在這裡插入圖片描述

前端查詢發來search請求

public class SearchProductServiceImpl implements SearchProductService {
    @Autowired
    JestClient jestClient;

    @Override
    public SearchResponse searchProduct(SearchParam searchParam) {
        //1、構建檢索條件
        String dsl = buildDsl(searchParam);

        log.error("商品檢索的詳細資料{}",dsl);


        Search search = new Search.Builder(dsl).addIndex(EsConstant.PRODUCT_ES_INDEX)
                .addType(EsConstant.PRODUCT_INFO_ES_TYPE)
                .build();

        SearchResult execute = null;
        try {
            //2、檢索
            execute = jestClient.execute(search);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //3、將返回的SearchResult轉為SearchResponse
        SearchResponse searchResponse = buildSearchResponse(execute);


        searchResponse.setPageNum(searchParam.getPageNum());
        searchResponse.setPageSize(searchParam.getPageSize());

        return searchResponse;
    }

聚合三大聚,分別為品牌聚,分類聚,屬性聚

相關文章