商城检索 DSL

编程入门 行业动态 更新时间:2024-10-10 17:27:27

<a href=https://www.elefans.com/category/jswz/34/1769605.html style=商城检索 DSL"/>

商城检索 DSL

  • 模糊匹配
  • 过滤(按照属性、分类、品牌、价格区间、库存)
  • 排序
  • 分页
  • 高亮
  • 聚合分析

一. 搜索关键字

检索字段:商品sku标题

“skuTitle” : “华为 HUAWEI Mate 30 Pro 亮黑色 8GB+256GB麒麟990旗舰芯片OLED环幕屏双4000万徕卡电影四摄4G全网通手机”

bool复合查询,must必须,全文检索字段用 match,其他非 text 字段匹配用 term

GET product/_search
{"query": {"bool": {"must": [{"match": {"skuTitle": "华为"}}]}}
}

二. 检索分类


检索字段:分类id

“catalogId” : 225

match会计算热度评分,filter不计算分数效率更快,所有把不需要热度评分的字段放大filter
全文检索字段用 match,其他非 text 字段匹配用 term

GET product/_search
{"query": {"bool": {"must": [{"match": {"skuTitle": "华为"}}],"filter": {"term": {"catalogId": "225"}}}}
}

三. 检索品牌


品牌是可以多选的,检索条件为品牌id的集合
terms等价于mysql 的 in()

检索字段:品牌Id

“brandId” : 9

GET product/_search
{"query": {"bool": {"must": [{"match": {"skuTitle": "华为"}}],"filter": [{"term": {"catalogId": "225"}},{"terms": {"brandId": ["1","2","9"]}}]}}
}

四. 检索属性

: attrId----------attrValue
属性可多选
查询attrs属性下嵌入的属性attr_id需要使用nested 嵌套查询

"attrs" : [{"attrId" : 15,"attrName" : "CPU品牌","attrValue" : "高通(Qualcomm)"},{"attrId" : 16,"attrName" : "CPU型号","attrValue" : "骁龙855"}]

检索字段:属性id、属性值

“attrId” : 15,
“attrValue” : “高通(Qualcomm)”

GET product/_search
{"query": {"bool": {"must": [{"match": {"skuTitle": "华为"}}],"filter": [{"term": {"catalogId": "225"}},{"terms": {"brandId": ["1","2","9"]}},{"nested": {"path": "attrs","query": {"bool": {"must": [{"term": {"attrs.attrId": {"value": "15"}}},{"terms": {"attrs.attrValue": ["高通(Qualcomm)","以官网信息为准"]}}]}}}}]}}
}

五. 检索库存、排序、价格区间、分页

查询是否有库存

排序

查询价格区间

分页
from从第几页开始,size查询几天记录

六.修改映射

{"gulimall_product" : {"mappings" : {"properties" : {"attrs" : {"type" : "nested","properties" : {"attrId" : {"type" : "long"},"attrName" : {"type" : "keyword"},"attrValue" : {"type" : "keyword"}}},"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"}}}}
}

七.动态聚合

根据检索的条件,查到数据后,根据结果聚合,动态的展示搜索的属性内容
例:如何搜索了机身内存 128G,那么刷新页面后就不会展示机身内存这一栏属性

聚合terms
聚合中的terms 会按照字段的值来分类,结果使用doc_count展示

比如性别有男、女,就会创建两个桶,分别存放男女的信息。默认会搜集doc_count的信息,即记录有多少男生,有多少女生,然后返回给客户端,这样就完成了一个terms得统计。

//GET gulimall_product/_search
{"query": {"bool": {"must": [{"match": {"skuTitle": "华为"}}],"filter": [{"term": {"catalogId": "225"}},{"terms": {"brandId": ["1","2","9"]}},{"nested": {"path": "attrs","query": {"bool": {"must": [{"term": {"attrs.attrId": {"value": "15"}}},{"terms": {"attrs.attrValue": ["高通(Qualcomm)","以官网信息为准"]}}]}}}},{"term": {"hasStock": {"value": "false"}}},{"range": {"skuPrice": {"gte": 0,"lte": 6000}}}]}},"sort": [{"skuPrice": {"order": "desc"}}],"from": 0,"size": 1,"highlight": {"fields": {"skuTitle": {}},"pre_tags": "<b style='color:red'>","post_tags": "</b>"},"aggs": {"brand_agg": {"terms": {"field": "brandId","size": 10},"aggs": {"brand_name_agg": {"terms": {"field": "brandName","size": 10}},"brand_img_agg": {"terms": {"field": "brandImg","size": 10}}}},"catalog_agg": {"terms": {"field": "catalogId","size": 10},"aggs": {"catalog_name_agg": {"terms": {"field": "catalogName","size": 10}}}},"attr_agg": {"nested": {"path": "attrs"},"aggs": {"attr_id_agg": {"terms": {"field": "attrs.attrId","size": 10},"aggs": {"attr_name_agg": {"terms": {"field": "attrs.attrName","size": 10}},"attr_value_agg": {"terms": {"field": "attrs.attrValue","size": 10}}}}}}}
}

八.后端构建DSL

//构建dsl语句private SearchRequest buildSearchRequest(SearchParam searchParam){SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();//最外层boolBoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();/*** 1.must*/if (!StringUtils.isEmpty(searchParam.getKeyword())){boolQueryBuilder.must(QueryBuilders.matchQuery("skuTitle",searchParam.getKeyword()));}/*** 2.filter*///分类if (searchParam.getCatalog3Id() != null){boolQueryBuilder.filter(QueryBuilders.termQuery("catalogId",searchParam.getCatalog3Id()));}//品牌if (null != searchParam.getBrand_id() && searchParam.getBrand_id().size() > 0){boolQueryBuilder.filter(QueryBuilders.termsQuery("brandId",searchParam.getBrand_id()));}//属性if (searchParam.getAttrs() != null && searchParam.getAttrs().size() > 0){//带多少值就有多少NestedQueryBuilder//attrs=1_5寸:8寸 & attrs=2_16G:8Gfor (String attrStr : searchParam.getAttrs()) {BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();//"attrs.attrId"String[] s = attrStr.split("_");//[1,5寸:8寸]//"attrs.attrValue"String[] split = s[1].split(":");//[5寸,8寸]//queryboolQuery.must(QueryBuilders.termQuery("attrs.attrId", s[0]));boolQuery.must(QueryBuilders.termsQuery("attrs.attrValue",split));//nestedQuery(String path, QueryBuilder query, ScoreMode scoreMode)NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("attrs", boolQuery, ScoreMode.None);boolQueryBuilder.filter(nestedQueryBuilder);}}//是否库存if (searchParam.getHasStock() != null){//传0,1,  es存的boolboolQueryBuilder.filter(QueryBuilders.termQuery("hasStock",searchParam.getHasStock()==1));}//价格区间if (!StringUtils.isEmpty(searchParam.getSkuPrice())){RangeQueryBuilder rangeQueryBuilder = new RangeQueryBuilder("skuPrice");//1_500/_500/500_String[] s = searchParam.getSkuPrice().split("_");//_500if (searchParam.getSkuPrice().startsWith("_")){rangeQueryBuilder.lte(s[1]);}//500_if (searchParam.getSkuPrice().endsWith("_")){rangeQueryBuilder.gte(s[0]);}//1_500if (s.length == 2 && StringUtils.isNotBlank(s[0])&&StringUtils.isNotBlank(s[1])){rangeQueryBuilder.gte(s[0]).lte(s[1]);}boolQueryBuilder.filter(rangeQueryBuilder);}//封装全部查询条件searchSourceBuilder.query(boolQueryBuilder);/*** 3.排序、分页、高亮*///排序if (!StringUtils.isEmpty(searchParam.getSort())){//根据热点评分排序sort=hotScore_asc/descString[] s = searchParam.getSort().split("_");SortOrder sortOrder = s[1].equalsIgnoreCase("asc") ? SortOrder.ASC: SortOrder.DESC;searchSourceBuilder.sort(s[0],sortOrder);}//分页//from = (pageNum - 1) * pageSizesearchSourceBuilder.from((searchParam.getPageNum() - 1) * EsConstant.GULIMALL_PRODUCT_PAGESIZE);searchSourceBuilder.size(EsConstant.GULIMALL_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);}/*** 4.聚合*///brand_aggTermsAggregationBuilder aggregationBuilder1 = AggregationBuilders.terms("brand_agg").field("brandId").size(50);aggregationBuilder1.subAggregation(AggregationBuilders.terms("brand_name_agg").field("brandName").size(1));aggregationBuilder1.subAggregation(AggregationBuilders.terms("brand_img_agg").field("brandImg").size(1));searchSourceBuilder.aggregation(aggregationBuilder1);//catalog_aggTermsAggregationBuilder aggregationBuilder2 = AggregationBuilders.terms("catalog_agg").field("catalogId").size(20);aggregationBuilder2.subAggregation(AggregationBuilders.terms("catalog_name_agg").field("catalogName").size(1));searchSourceBuilder.aggregation(aggregationBuilder2);//attr_aggNestedAggregationBuilder nested = AggregationBuilders.nested("attr_agg", "attrs");TermsAggregationBuilder attr_id_agg = AggregationBuilders.terms("attr_id_agg").field("attrs.attrId").size(10);nested.subAggregation(attr_id_agg);attr_id_agg.subAggregation(AggregationBuilders.terms("attr_name_agg").field("attrs.attrName").size(1));attr_id_agg.subAggregation(AggregationBuilders.terms("attr_value_agg").field("attrs.attrValue").size(50));searchSourceBuilder.aggregation(nested);System.out.println("DSL测试成功:" + searchSourceBuilder.toString());//返回数据//SearchRequest(String[] indices, SearchSourceBuilder source) {SearchRequest searchRequest = new SearchRequest(new String[]{EsConstant.GULIMALL_PRODUCT_INDEX},searchSourceBuilder);return  searchRequest;}

九. DSL返回结果封装

	  /*** 通过 首页检索条件 或 分类  查询页面*/@Overridepublic SearchResult search(SearchParam searchParam) throws IOException {//构建DSLSearchRequest searchRequest = buildSearchRequest(searchParam);SearchResult searchResult = null;try {//发送检索请求SearchResponse searchResponse = client.search(searchRequest, GulimallElasticSearchConfig.COMMON_OPTIONS);//分析响应数据,转换成需要的格式searchResult = buildSearchResult(searchResponse,searchParam);} catch (IOException e) {e.printStackTrace();}return searchResult;}private SearchResult buildSearchResult(SearchResponse searchResponse,SearchParam param) {SearchResult result = new SearchResult();SearchHits hits = searchResponse.getHits();List<SkuEsModel> modelList = new ArrayList<>();SearchHit[] hitArray = hits.getHits();for (SearchHit documentFields : hitArray) {String string = documentFields.getSourceAsString();SkuEsModel skuEsModel = JSON.parseObject(string, SkuEsModel.class);modelList.add(skuEsModel);//高亮if (!StringUtils.isEmpty(param.getKeyword())){//如果传了检索条件,我们的结果才使用高亮HighlightField skuTitle = documentFields.getHighlightFields().get("skuTitle");Text[] fragments = skuTitle.fragments();String s = fragments[0].toString();skuEsModel.setSkuTitle(s);}}//查询所有商品信息result.setProducts(modelList);//分页信息long total = hits.getTotalHits().value;result.setPageNum(param.getPageNum());result.setTotal(total);//总页码计算:10/2 5 totalPage=5 , 11/2=5..1int count = (int)total / (int)EsConstant.GULIMALL_PRODUCT_PAGESIZE;result.setTotalPages(total % EsConstant.GULIMALL_PRODUCT_PAGESIZE == 0 ? count : ++count);Aggregations aggregations = searchResponse.getAggregations();//品牌信息List<SearchResult.BrandVo> brands = new ArrayList<>();ParsedLongTerms brand_agg = aggregations.get("brand_agg");for (Terms.Bucket bucket : brand_agg.getBuckets()) {SearchResult.BrandVo brandVo = new SearchResult.BrandVo();//brandIdlong brandId = bucket.getKeyAsNumber().longValue();brandVo.setBrandId(brandId);//brandNameParsedStringTerms brand_name_agg = bucket.getAggregations().get("brand_name_agg");String brand_name = brand_name_agg.getBuckets().get(0).getKeyAsString();brandVo.setBrandName(brand_name);//brandImgParsedStringTerms brand_img_agg = bucket.getAggregations().get("brand_img_agg");String brand_img   = brand_img_agg.getBuckets().get(0).getKeyAsString();brandVo.setBrandImg(brand_img);brands.add(brandVo);}result.setBrands(brands);//分类信息List<SearchResult.CatalogVo> catalogVoList = new ArrayList<>();ParsedLongTerms catalog_agg = aggregations.get("catalog_agg");for (Terms.Bucket bucket : catalog_agg.getBuckets()) {SearchResult.CatalogVo catalogVo = new SearchResult.CatalogVo();//catalogIdcatalogVo.setCatalogId(Long.parseLong(bucket.getKeyAsString()));//catalogNameParsedStringTerms catalog_name_agg = bucket.getAggregations().get("catalog_name_agg");String catalogName = catalog_name_agg.getBuckets().get(0).getKeyAsString();catalogVo.setCatalogName(catalogName);catalogVoList.add(catalogVo);}result.setCatalogs(catalogVoList);//属性信息List<SearchResult.AttrVo> attrs = new ArrayList<>();ParsedNested attr_agg = aggregations.get("attr_agg");ParsedLongTerms attr_id_agg = attr_agg.getAggregations().get("attr_id_agg");for (Terms.Bucket bucket : attr_id_agg.getBuckets()) {SearchResult.AttrVo attrVo = new SearchResult.AttrVo();Long attrId = bucket.getKeyAsNumber().longValue();//attrIdattrVo.setAttrId(attrId);//attrNameParsedStringTerms attr_name_agg = bucket.getAggregations().get("attr_name_agg");String attrName = attr_name_agg.getBuckets().get(0).getKeyAsString();attrVo.setAttrName(attrName);//attrValueParsedStringTerms attr_value_agg = bucket.getAggregations().get("attr_value_agg");List<String> collect = attr_value_agg.getBuckets().stream().map(item -> {return item.getKeyAsString();}).collect(Collectors.toList());attrVo.setAttrValue(collect);attrs.add(attrVo);}result.setAttrs(attrs);//6、构建面包屑导航if (param.getAttrs() != null && param.getAttrs().size() > 0) {List<SearchResult.NavVo> collect = param.getAttrs().stream().map(attr -> {//1、分析每一个attrs传过来的参数值SearchResult.NavVo navVo = new SearchResult.NavVo();String[] s = attr.split("_");navVo.setNavValue(s[1]);//R r = productFeignService.attrInfo(Long.parseLong(s[0]));result.getAttrIds().add(Long.parseLong(s[0]));if (r.getCode() == 0) {AttrResponseVo data = (AttrResponseVo)r.getData("attr", new TypeReference<AttrResponseVo>() {});navVo.setNavName(data.getAttrName());} else {navVo.setNavName(s[0]);}//2、取消了这个面包屑以后,我们要跳转到哪个地方,将请求的地址url里面的当前置空//拿到所有的查询条件,去掉当前String replace = replaceQueryString(param, attr,"attrs");navVo.setLink(".html?" + replace);return navVo;}).collect(Collectors.toList());result.setNavs(collect);}//品牌分类if (param.getBrand_id() != null && param.getBrand_id().size() > 0){List<SearchResult.NavVo> navs = result.getNavs();SearchResult.NavVo navVo = new SearchResult.NavVo();navVo.setNavName("品牌");//TODO 远程查所有品牌R r = productFeignService.brandsInfo(param.getBrand_id());if (r.getCode() == 0){List<BrandVo> brand =  (List<BrandVo>)r.getData("brand",new TypeReference<List<BrandVo>>(){});StringBuffer buffer = new StringBuffer();String replace = "";for (BrandVo brandVo : brand) {buffer.append(brandVo.getBrandName()+";");replace = replaceQueryString(param, brandVo.getBrandId()+"","brandId");}navVo.setNavValue(buffer.toString());navVo.setLink(".html?" + replace);}navs.add(navVo);}return result;}

更多推荐

商城检索 DSL

本文发布于:2024-02-12 00:26:37,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1684590.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:商城   DSL

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!