谷粒商城 es的检索运用,searchrequest的构建

1.使用javaApi接口创建searchrequest:

/**
     * 构建检索请求:
     * #模糊匹配,过滤(按照属性,分类,品牌,价格区间,库存),排序,分页,高亮,聚合分析
     * */
    private SearchRequest buildSearchRequest(SearchParam searchParam) {
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();//构建DSL语句
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        /**
         * 模糊匹配,过滤(按照属性,分类,品牌,价格区间,库存)
         * */
        //1.构建bool-query
        //1.1 模糊匹配 bool - must
        if (!StringUtils.isEmpty(searchParam.getKeyWord())){
            boolQueryBuilder.must(QueryBuilders.matchQuery("skuTitle",searchParam.getKeyWord()));
        }
        //1.2 bool - filter 按照三级分类id查询
        if (searchParam.getCatalog3Id()!=null){
            boolQueryBuilder.filter(QueryBuilders.termQuery("catalogId",searchParam.getCatalog3Id()));
        }
        //1.3 bool -filter  按照品牌id查询
        if (searchParam.getBrandId()!=null&&searchParam.getBrandId().size()>0){
            boolQueryBuilder.filter(QueryBuilders.termsQuery("brandId",searchParam.getBrandId()));
        }
        //1.4 bool -filter - nested  按照指定的属性查询
        if (searchParam.getAttrs()!=null&&searchParam.getAttrs().size()>0){
            //每一个属性查询必须都得生成一个nested查询
            for (String attr : searchParam.getAttrs()) {
                BoolQueryBuilder nestedBoolQuery = QueryBuilders.boolQuery();
                //attrs=1_5寸:8寸&attrs=2_16G:8G
                String[] attrSplit = attr.split("_");
                String attrId = attrSplit[0];
                String[] attrValues = attrSplit[1].split(":");
                nestedBoolQuery.must(QueryBuilders.termQuery("attrs.attrId",attrId));
                nestedBoolQuery.must(QueryBuilders.termsQuery("attrs.attrValue",attrValues));
                //每一个必须都得生成一个nested查询
                NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery("attrs", nestedBoolQuery, ScoreMode.None);
                boolQueryBuilder.filter(nestedQuery);
            }
        }
        //1.5 bool -filter 是否有库存查询
        if (searchParam.getHasStock()==null){
            //如果没有传输是否有库存这个参数,默认查找有库存的
            boolQueryBuilder.filter(QueryBuilders.termQuery("hasStock",true));
        }else {
            boolQueryBuilder.filter(QueryBuilders.termQuery("hasStock",searchParam.getHasStock()==1));
        }

        //1.6按照价格区间
        if (!StringUtils.isEmpty(searchParam.getSkuPrice())){
            RangeQueryBuilder skuPriceRangeQuery = QueryBuilders.rangeQuery("skuPrice");
            String[] s = searchParam.getSkuPrice().split("_");
            if (s.length == 2 ){
                //区间
                skuPriceRangeQuery.gte(s[0]).lte(s[1]);
            }else if (s.length==1){
                if (searchParam.getSkuPrice().startsWith("_")){
                    skuPriceRangeQuery.lte(s[0]);
                }
                if (searchParam.getSkuPrice().endsWith("_")){
                    skuPriceRangeQuery.gte(s[0]);
                }
            }
            boolQueryBuilder.filter(skuPriceRangeQuery);
        }
        searchSourceBuilder.query(boolQueryBuilder);

        /**
         * 排序,分页,
         *       sort=saleCount_asc/desc
         *       sort=skuPrice_asc/desc
         *       sort= hotScore_asc/desc
         * */
        if (!StringUtils.isEmpty(searchParam.getSort())){
            String sort = searchParam.getSort();
            String[] sortSplit = sort.split("_");
            SortOrder sortOrder = sortSplit[1].equalsIgnoreCase("asc")?SortOrder.ASC:SortOrder.DESC;
            searchSourceBuilder.sort(sortSplit[0],sortOrder);
        }
        //分页
        if (searchParam.getPageNum()==null){
            //如果没有传输pagenum参数,默认为第一页
            searchSourceBuilder.from(((1-1)*EsConstant.PRODUCT_PAGESIZE));
            searchSourceBuilder.size(EsConstant.PRODUCT_PAGESIZE);
        }else {
            searchSourceBuilder.from((searchParam.getPageNum()-1)*EsConstant.PRODUCT_PAGESIZE);
            searchSourceBuilder.size(EsConstant.PRODUCT_PAGESIZE);
        }

        /**
         * 高亮
         * */
        if (!StringUtils.isEmpty(searchParam.getKeyWord())){
            HighlightBuilder highlightBuilder=new HighlightBuilder();
            highlightBuilder.field("skuTitle");
            highlightBuilder.preTags("<b style= 'color:red'>");
            highlightBuilder.postTags("</b>");
            searchSourceBuilder.highlighter(highlightBuilder);
        }
        /**
         * 聚合分析
         * */

        //1.品牌的聚合
        TermsAggregationBuilder brand_agg = AggregationBuilders.terms("brand_agg");
        brand_agg.field("brandId");
        //品牌的子聚合
        brand_agg.subAggregation(AggregationBuilders.terms("brand_name_agg").field("brandName").size(1));
        brand_agg.subAggregation(AggregationBuilders.terms("brand_img_agg").field("brandImg").size(1));
        //TODO 1. 品牌的聚合
        searchSourceBuilder.aggregation(brand_agg);
        //2.分类聚合 catalog_agg
        TermsAggregationBuilder catalog_agg = AggregationBuilders.terms("catalog_agg").field("catalogId").size(20);
        catalog_agg.subAggregation(AggregationBuilders.terms("catalog_name_agg").field("catalogName").size(1));
        //TODO 2. 分类的聚合
        searchSourceBuilder.aggregation(catalog_agg);
        //3.属性聚合 attr_agg
        NestedAggregationBuilder attr_agg = AggregationBuilders.nested("attr_agg", "attrs");
        //3.1聚合当前所有的attrId
        TermsAggregationBuilder attr_id_agg = AggregationBuilders.terms("attr_id_agg").field("attrs.attrId").size(10);
        //3.2聚合分析出当前attr_id对应的名字
        attr_id_agg.subAggregation(AggregationBuilders.terms("attr_name_agg").field("attrs.attrName").size(1));
        //3.3聚合分析出当前attr_id对应的所有可能的属性值attrValue
        attr_id_agg.subAggregation(AggregationBuilders.terms("attr_value_agg").field("attrs.attrValue").size(50));
        attr_agg.subAggregation(attr_id_agg);
        //TODO 3. 属性的聚合
        searchSourceBuilder.aggregation(attr_agg);
        //打印构造的DSL
        String s = searchSourceBuilder.toString();
        System.out.println("构建的DSL:"+s);

        SearchRequest searchRequest = new SearchRequest(new String[]{EsConstant.PRODUCT_INDEX}, searchSourceBuilder);
        return searchRequest;
    }

2.传递过来的参数:

http://localhost:12000/list.html?keyWord=HUAWEI&catalog3Id=225&attrs=11_第一代骁龙8&skuPrice=4000_

3.使用postman发送形成的DSL语句:

GET product/_search
{
  "from": 0,
  "size": 5,
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "skuTitle": {
              "query": "HUAWEI",
              "operator": "OR",
              "prefix_length": 0,
              "max_expansions": 50,
              "fuzzy_transpositions": true,
              "lenient": false,
              "zero_terms_query": "NONE",
              "auto_generate_synonyms_phrase_query": true,
              "boost": 1.0
            }
          }
        }
      ],
      "filter": [
        {
          "term": {
            "catalogId": {
              "value": 225,
              "boost": 1.0
            }
          }
        },
        {
          "nested": {
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "attrs.attrId": {
                        "value": "11",
                        "boost": 1.0
                      }
                    }
                  },
                  {
                    "terms": {
                      "attrs.attrValue": [
                        "第一代骁龙8"
                      ],
                      "boost": 1.0
                    }
                  }
                ],
                "adjust_pure_negative": true,
                "boost": 1.0
              }
            },
            "path": "attrs",
            "ignore_unmapped": false,
            "score_mode": "none",
            "boost": 1.0
          }
        },
        {
          "term": {
            "hasStock": {
              "value": true,
              "boost": 1.0
            }
          }
        },
        {
          "range": {
            "skuPrice": {
              "from": "4000",
              "to": null,
              "include_lower": true,
              "include_upper": true,
              "boost": 1.0
            }
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1.0
    }
  },
  "aggregations": {
    "brand_agg": {
      "terms": {
        "field": "brandId",
        "size": 10,
        "min_doc_count": 1,
        "shard_min_doc_count": 0,
        "show_term_doc_count_error": false,
        "order": [
          {
            "_count": "desc"
          },
          {
            "_key": "asc"
          }
        ]
      },
      "aggregations": {
        "brand_name_agg": {
          "terms": {
            "field": "brandName",
            "size": 1,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        },
        "brand_img_agg": {
          "terms": {
            "field": "brandImg",
            "size": 1,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        }
      }
    },
    "catalog_agg": {
      "terms": {
        "field": "catalogId",
        "size": 20,
        "min_doc_count": 1,
        "shard_min_doc_count": 0,
        "show_term_doc_count_error": false,
        "order": [
          {
            "_count": "desc"
          },
          {
            "_key": "asc"
          }
        ]
      },
      "aggregations": {
        "catalog_name_agg": {
          "terms": {
            "field": "catalogName",
            "size": 1,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        }
      }
    },
    "attr_agg": {
      "nested": {
        "path": "attrs"
      },
      "aggregations": {
        "attr_id_agg": {
          "terms": {
            "field": "attrs.attrId",
            "size": 10,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          },
          "aggregations": {
            "attr_name_agg": {
              "terms": {
                "field": "attrs.attrName",
                "size": 1,
                "min_doc_count": 1,
                "shard_min_doc_count": 0,
                "show_term_doc_count_error": false,
                "order": [
                  {
                    "_count": "desc"
                  },
                  {
                    "_key": "asc"
                  }
                ]
              }
            },
            "attr_value_agg": {
              "terms": {
                "field": "attrs.attrValue",
                "size": 50,
                "min_doc_count": 1,
                "shard_min_doc_count": 0,
                "show_term_doc_count_error": false,
                "order": [
                  {
                    "_count": "desc"
                  },
                  {
                    "_key": "asc"
                  }
                ]
              }
            }
          }
        }
      }
    }
  },
  "highlight": {
    "pre_tags": [
      "<b style= 'color:red'>"
    ],
    "post_tags": [
      "</b>"
    ],
    "fields": {
      "skuTitle": {}
    }
  }
}

4.查询到的结果:

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.66301036,
    "hits" : [
      {
        "_index" : "product",
        "_type" : "_doc",
        "_id" : "7",
        "_score" : 0.66301036,
        "_source" : {
          "attrs" : [
            {
              "attrId" : 11,
              "attrName" : "CPU型号",
              "attrValue" : "第一代骁龙8"
            }
          ],
          "brandId" : 4,
          "brandImg" : "https://gulimall-nan1.oss-cn-beijing.aliyuncs.com/2022-11-30/90b15473-072f-42d4-8c35-11a6cd1161ac_huawei.png",
          "brandName" : "华为",
          "catalogId" : 225,
          "catalogName" : "手机",
          "hasStock" : true,
          "hotScore" : 0,
          "saleCount" : 0,
          "skuId" : 7,
          "skuImg" : "https://gulimall-nan1.oss-cn-beijing.aliyuncs.com/2022-12-05//ff79ccd7-f380-4805-86aa-17624e2f59e3_d511faab82abb34b.jpg",
          "skuPrice" : 4999.0,
          "skuTitle" : "HUAWEI Mate 50 冰霜银 8+128GB直屏旗舰 超光变XMAGE影像 北斗卫星消息 低电量应急模式",
          "spuId" : 15
        },
        "highlight" : {
          "skuTitle" : [
            "<b style= 'color:red'>HUAWEI</b> Mate 50 冰霜银 8+128GB直屏旗舰 超光变XMAGE影像 北斗卫星消息 低电量应急模式"
          ]
        }
      }
    ]
  },
  "aggregations" : {
    "catalog_agg" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : 225,
          "doc_count" : 1,
          "catalog_name_agg" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "手机",
                "doc_count" : 1
              }
            ]
          }
        }
      ]
    },
    "attr_agg" : {
      "doc_count" : 1,
      "attr_id_agg" : {
        "doc_count_error_upper_bound" : 0,
        "sum_other_doc_count" : 0,
        "buckets" : [
          {
            "key" : 11,
            "doc_count" : 1,
            "attr_name_agg" : {
              "doc_count_error_upper_bound" : 0,
              "sum_other_doc_count" : 0,
              "buckets" : [
                {
                  "key" : "CPU型号",
                  "doc_count" : 1
                }
              ]
            },
            "attr_value_agg" : {
              "doc_count_error_upper_bound" : 0,
              "sum_other_doc_count" : 0,
              "buckets" : [
                {
                  "key" : "第一代骁龙8",
                  "doc_count" : 1
                }
              ]
            }
          }
        ]
      }
    },
    "brand_agg" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : 4,
          "doc_count" : 1,
          "brand_img_agg" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "https://gulimall-nan1.oss-cn-beijing.aliyuncs.com/2022-11-30/90b15473-072f-42d4-8c35-11a6cd1161ac_huawei.png",
                "doc_count" : 1
              }
            ]
          },
          "brand_name_agg" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "华为",
                "doc_count" : 1
              }
            ]
          }
        }
      ]
    }
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值