商城业务检索请求分析封装

简介: 商城业务检索请求分析封装

请求参数封装对象如下

/**
* 封装页面所有可能传递进来的查询条件
* catalog3Id=225&keyword=小米&sort=saleCount_asc&hasStock=0/1&attrs
*/

@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;//排序条件
    /**
     * 过滤条件
     * hasStock(是否有货) skuPrice(价格区间) brandId catalog3Id attrs
     * hasStock=0/1;
     * skuPrice=1_500/_500/500_
     * brandId=1
     */
    private  Integer hasStock=1;// 是否只显示有货
    private  String skuPrice;//价格区间查询
    private List<Long> brandId;//品牌id 可以多选
    private  List<String> attrs;//按照属性进行筛选
    private  Integer pageNum=1;
}

数据迁移代码如下

PUT gulimall_product
{
  "mappings": {
    "properties": {
      "attrs": {
        "type": "nested",
        "properties": {
          "attrId": {
            "type": "long"
          },
          "attrName": {
            "type": "keyword"
          },
          "attrValue": {
            "type": "keyword"
          }
        }
      },
      "bandId": {
        "type": "long"
      },
      "brandId": {
        "type": "long"
      },
      "brandImg": {
        "type": "keyword"
      },
      "brandName": {
        "type": "keyword"
      },
      "catalogId": {
        "type": "long"
      },
      "catalogName": {
        "type": "keyword"
      },
      "hasStock": {
        "type": "boolean"
      },
      "hotScore": {
        "type": "long"
      },
      "saleCount": {
        "type": "long"
      },
      "skuId": {
        "type": "long"
      },
      "skuImg": {
        "type": "keyword"
      },
      "skuPrice": {
        "type": "keyword"
      },
      "skuTitle": {
        "type": "text",
        "analyzer": "ik_smart"
      },
      "spuId": {
        "type": "keyword"
      }
    }
  }
}
GET gulimall_product/_search
#迁移数据
POST _reindex
{
  "source": {
    "index": "product"
  },
  "dest": {
    "index":"gulimall_product"
  }

控制层请求如下

    /**
     * pringmvc将页面提交过来的全部参数封装成指定对象
     * @param param
     * @return
     */
    @GetMapping("/list.html")
    public String listPage(SearchParam param, Model model){
       SearchResult result= mallSearchService.search(param);
        model.addAttribute("result",result);
        return "list";
    }

请求封装思路如下

@Service
public class MallSearchServiceImpl implements MallSearchService {
    @Autowired
    private RestHighLevelClient client;
    /**
     * 去es查
     * @param param 检索的参数
     * @return
     */
    @Override
    public SearchResult search(SearchParam param) {
        //1.动态构建出查询需要的dsl语句
        SearchResult result = new SearchResult();
        //1.准备检索请求
        SearchRequest searchRequest   =buildSearchRequest(param);
        try {
            //2.执行检索请求
            SearchResponse response = client.search(searchRequest, GulimallElasticSearchConfig.COMMON_OPTIONS);
            //3.分析响应数据封装成我们需要的格式
            result  = buildSearchResult(response)
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
    /**
     * 准备检索请求
     * @return
     */
    private SearchRequest buildSearchRequest(SearchParam param) {
    }
    /**
     * 构建结果数据
     * @param response
     * @return
     */
    private SearchResult buildSearchResult(SearchResponse response) {
    }
}

请求dsl语句api封装

 /**
     * 准备检索请求
     *
     * @return
     */
    private SearchRequest buildSearchRequest(SearchParam param) {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();//构建dsl语句
        /**
         * 查询:模糊匹配,过滤(按照属性,分类。品牌,价格区间,库存)
         */
        //构建bool query
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //1.1  must
        if (!StringUtils.isEmpty(param.getKeyword())){
            boolQuery.must(QueryBuilders.matchQuery("skuTitle",param.getKeyword()));
        }
        //1.2 bool filter --按照三级分类查询的
        if (param.getCatalog3Id()!=null){
            boolQuery.filter(QueryBuilders.termQuery("catalogId",param.getCatalog3Id()));
        }
        //1.32 bool filter -按照品牌id过滤
        if (param.getBrandId()!=null&&param.getBrandId().size()>0){
            boolQuery.filter(QueryBuilders.termQuery("brandId",param.getBrandId()));
        }
        //1.2 bool filter -按照所有指定属性进行查询
        if(param.getAttrs()!=null&&param.getAttrs().size()>0){
            //attrs=1_5寸:8寸
            for (String attrStr : param.getAttrs()) {
                BoolQueryBuilder nestedboolQuery = QueryBuilders.boolQuery();
                String[] s = attrStr.split("_");
                String attrId= s[0];//属性id
                String[] attrValues = s[1].split(":");//属性值
                nestedboolQuery.must(QueryBuilders.termQuery("attrs.attrId",attrId));
                nestedboolQuery.must(QueryBuilders.termQuery("attrs.attrValue",attrValues));
                NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery("attrs", nestedboolQuery, ScoreMode.None);
                boolQuery.filter(nestedQuery);
            }
        }
        //1.2 bool filter -按照库存是否有进行查询
        boolQuery.filter(QueryBuilders.termQuery("hasStock",param.getHasStock()==1));
        //1.2 bool filter -按照价格区间进行查询
        if(!StringUtils.isEmpty(param.getSkuPrice())){
            //1_500/_500/500_
            RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("skuPrice");
            String[] s = param.getSkuPrice().split("_");
            if (s.length==2){
                //区间
                rangeQuery.gte(s[0]).lte(s[1]);
            }else if (s.length==1){
                if(param.getSkuPrice().startsWith("_")){
                    rangeQuery.lte(s[0]);
                }else {
                    rangeQuery.gte(s[0]);
                }
            }
            boolQuery.filter(rangeQuery);
        }
        //把以前的所有条件来进行封装
        sourceBuilder.query(boolQuery);
        /**
         * 排序,分页,高亮
         */
        //2.1 排序
         if(!StringUtils.isEmpty(param.getSort())) {
             String sort = param.getSort();
             String[] s = sort.split("_");
             SortOrder order=s[1].equalsIgnoreCase("asc")?SortOrder.ASC:SortOrder.DESC;
             sourceBuilder.sort(s[0], order);
         }
         //2.2分页
        //
         sourceBuilder.from((param.getPageNum()-1)*EsConstant.PRODUCT_PAGESIZE);
         sourceBuilder.size(EsConstant.PRODUCT_PAGESIZE);
        //2.3 高亮 传keyword模糊匹配的时候
        if (!StringUtils.isEmpty(param.getKeyword())){
            HighlightBuilder builder = new HighlightBuilder();
            builder.field("skuTitle");
            builder.preTags("<b style='color:red'>");
            builder.postTags("</b>");
            sourceBuilder.highlighter(builder);
        }
        /**
         * 聚合分析
         */
        //1.品牌聚合
        TermsAggregationBuilder brand_agg = AggregationBuilders.terms("brand_agg");
        brand_agg.field("brandId").size(50);
        //品牌聚合的子聚合
        brand_agg.subAggregation(AggregationBuilders.terms("brand_name_agg").field("brandName").size(1));
        brand_agg.subAggregation(AggregationBuilders.terms("brand_img_agg").field("brandImg").size(1));
        sourceBuilder.aggregation(brand_agg);
        //2.分类聚合
        TermsAggregationBuilder catalog_agg = AggregationBuilders.terms("catalog_agg").field("catalogId").size(20);
        catalog_agg.subAggregation(AggregationBuilders.terms("catalog_name_agg").field("catalogName").size(1));
        sourceBuilder.aggregation(catalog_agg);
        //3.属性聚合attr_agg
        NestedAggregationBuilder attr_agg = AggregationBuilders.nested("attr_agg", "attrs");
        //聚合出当前所有的attrId
        TermsAggregationBuilder attr_id_agg = AggregationBuilders.terms("attr_id_agg").field("attrs.attrId");
        //聚合分析出当前attr_id对应的名字
        attr_id_agg.subAggregation(AggregationBuilders.terms("attr_name_agg").field("attrs.attrName").size(1));
        //聚合分析出当前attr_id对应的所有可能的属性值
        attr_id_agg.subAggregation(AggregationBuilders.terms("attr_value_agg").field("attrs.attValue").size(50));
        attr_agg.subAggregation(attr_id_agg);
        //聚合attr
        sourceBuilder.aggregation(attr_agg);
        System.out.println(sourceBuilder.toString());
        SearchRequest searchRequest = new SearchRequest(new String[]{EsConstant.PRODUCT_INDEX},sourceBuilder);
        return  searchRequest;
    }
相关文章
|
7月前
|
小程序 物联网 程序员
【社区每周】“小程序商品”能力接口字段更新(10.23-10.29)
【社区每周】“小程序商品”能力接口字段更新(10.23-10.29)
74 10
|
4月前
|
自然语言处理 数据可视化 API
淘宝商品评论 API 接口:深度解析用户评论,优化产品与服务
淘宝是领先的中国电商平台,其API为开发者提供商品信息、交易记录及用户评价等数据访问服务。对于获授权的开发者和商家,可通过申请API权限、获取并解析评论数据来进行情感分析和统计,进而优化产品设计、提升服务质量、增强用户互动及调整营销策略。未授权用户可能受限于数据访问。
|
10天前
|
缓存 数据处理 数据安全/隐私保护
淘宝商品评论接口的高效数据处理技术
淘宝商品评论接口(即淘宝评论API)是专为开发者设计的一个强大工具,它允许开发者获取淘宝(包括天猫)平台上商品的详细评论信息。以下是关于淘宝商品评论接口关键技术的详细描述:
|
2月前
|
存储 数据可视化 API
API接口数据获取流程的细化
本文概述了API的基础知识、获取API访问权限的方法、编写代码调用API的步骤、数据处理与分析技巧以及数据安全与合规的重要性,并提供了社交媒体数据分析、天气预报应用和电商数据分析等API数据获取的应用实例,旨在帮助读者全面了解和实践API接口数据获取的流程。
|
2月前
|
安全 API 数据安全/隐私保护
商品详情API接口的优势分析与应用价值
在数字化时代,商品详情API接口为商家和开发者提供了实时更新、高效集成、丰富功能、安全稳定、易于扩展及提升用户体验的解决方案,助力提高运营效率、降低成本并增强市场竞争力。
|
5月前
|
JSON API 数据处理
深度解析京东商品列表数据接口:功能、参数与实战技巧
京东商品列表数据接口让开发者通过HTTP请求获取京东商品详尽列表信息,包括ID、名称、价格等。接口支持参数化搜索(关键词、价格区间等),返回JSON格式数据,便于处理与分析。开发者需注册账号并创建应用以获取访问权限。应用场景涵盖市场调研、商品管理和营销策略制定等,有效提升数据驱动决策能力。
|
4月前
|
JSON API 开发者
GET方式请求速卖通平台API 接口:商品列表数据获取指南
速卖通商品列表数据接口(如 `aliexpress.item_search`)让开发者获取商品信息列表, 包括名称、价格等关键数据。接口支持按关键词、分类ID等条件获取商品列表及详细信息, 并可通过分页与排序优化展示效果。开发者需在速卖通开放平台注册并创建应用获取API密钥, 构建HTTP请求并处理JSON响应数据。[体验API](http://b.mrw.so/2Pv6Qu)。
游戏对接广告看视频系统开发详细规则/方案逻辑/步骤逻辑/规则玩法/源码程序
Advertising location and display method: According to the characteristics of the game interface and scene, choose the appropriate advertising location and display method to ensure that the advertisement naturally integrates into the game and does not affect the player&#39;s game experience.
|
7月前
|
监控 供应链 测试技术
如何利用API接口进行高效的商品变体管理?
要利用API接口进行高效的商品变体管理,您需要执行一系列策略和技术步骤来确保数据的准确性和实时性。以下是详细的指南:
|
7月前
|
供应链 搜索推荐 BI
深入了解淘宝原数据:获取API接口及其使用场景
在当今数字化的时代,对于电商行业来说,数据具有极大的价值。淘宝作为中国最大的综合电商平台,拥有庞大的商品信息和用户数据。对于开发者和企业来说,淘宝原数据的获取和分析是实现个性化服务和精准营销的基础。本文将介绍如何通过API接口获取淘宝原数据,以及数据的使用场景。
下一篇
DataWorks