商品检索

作者: 异步_缓存_队排好 | 来源:发表于2019-05-29 19:13 被阅读0次

    ElasticSearch实现商品检索

    商品检索

    检索入口

    首页的分类 搜索栏

    复杂条件检索

    复杂条件筛选

    检索业务需要考虑的问题

    商品基本的数据模型

    product:{
    
            商品的基本信息,(需要检索的名字,关键字,分类等)
    
            商品的属性信息,(属性名+属性值+是否可以筛选,这些属性需要在平台进行筛选)
    
    }
    
    需要分词检索的字段 商品的名称(SKU销售属性参与),(副标题,关键字(加分项))
    需要过滤的字段 分类id,属性k&v组合 不分词
    需要显示的字段 商品标题(高亮),商品
    需要聚合的字段 品牌,分类,属性和值
    需要排序的字段 综合、销量、属性和值
    这些信息从哪里来?

    满足查询提交"小米"的所有商品的分布

    他们都涉及哪些品牌,涉及哪些分类,涉及哪些商品的可筛选属性参数,涉及哪些.....

    这些都是动态的,每一步不一样的都需要重新计算

    商品的ES对象模型

    EsProduct
    @Data
    public class EsProduct implements Serializable {
        private static final long serialVersionUID = -1L;
        private Long id;  //spuId
        private String productSn;  //spuId-skuId
        private Long brandId;
        private String brandName;
    
        private Long productCategoryId;
        private String productCategoryName;
        private String pic;
        private String name;//这是需要检索的字段 分词
        private String subTitle;//也可以检索,这是一个加分字段
        private String keywords;// 也可以检索,这是一个加分字段
        private BigDecimal price;//sku-price;
        private Integer sale;//sku-sale
        private Integer newStatus;//
        private Integer recommandStatus;//
        private Integer stock;//sku-stock
        private Integer promotionType;//促销类型
        private Integer sort;//排序
    private Integer commentCount;//评论数量共享spu
        private List<EsProductAttributeValue> attrValueList;//商品的筛选属性(SPU的属性; 
     网络制式:3G 4G 5G,
    操作系统:Android IO)
    
    EsProductAttributeValue
    @Data
    public class EsProductAttributeValue implements Serializable {
        private static final long serialVersionUID = 1L;
        private Long id;
        private Long productAttributeId;
        //属性值
        private String value;//3G
        //属性参数:0->规格;1->参数
        private Integer type;//规格,销售属性;参数,筛选参数
        //属性名称
        private String name;//网络制式
    
    }
    
    /**
     * 搜索相关商品品牌名称,分类名称及属性
     */
    @Data
    public class EsProductRelatedInfo {
        private List<String> brandNames;
        private List<String> productCategoryNames;
        private List<ProductAttr>   productAttrs;
    
    
        @Data
        public static class ProductAttr{
            private Long attrId;
            private String attrName;
            private List<String> attrValues;
        }
    }
    
    
    
    PUT /product
    {
      "mappings": {
        "info": {
          "properties": {
            "attrValueList": {
              "type":"nested",
              "properties": {
                "id": {
                  "type": "long"
                },
                "name": {
                  "type": "keyword"
                },
                "productAttributeId": {
                  "type": "long"
                },
                "productId": {
                  "type": "long"
                },
                "type": {
                  "type": "long"
                },
                "value": {
                  "type": "text",
                  "fields": {
                    "keyword": {
                      "type": "keyword",
                      "ignore_above": 256
                    }
                  }
                }
              }
            },
            "brandId": {
              "type": "long"
            },
            "brandName": {
              "type": "text",
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                }
              }
            },
            "id": {
              "type": "long"
            },
            "keywords": {
              "type": "text",
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                }
              }
            },
            "name": {
              "type": "text",
              "analyzer": "ik_max_word",
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                }
              }
            },
            "newStatus": {
              "type": "long"
            },
            "pic": {
              "type": "text",
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                }
              }
            },
            "price": {
              "type": "float"
            },
            "productCategoryId": {
              "type": "long"
            },
            "productCategoryName": {
              "type": "text",
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                }
              }
            },
            "productSn": {
              "type": "text",
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                }
              }
            },
            "promotionType": {
              "type": "long"
            },
            "recommandStatus": {
              "type": "long"
            },
            "sale": {
              "type": "long"
            },
            "skuProductInfos": {
              "type":"nested",
              "properties": {
                "attributeValues": {
                  "type":"nested",
                  "properties": {
                    "name": {
                      "type": "text",
                      "fields": {
                        "keyword": {
                          "type": "keyword",
                          "ignore_above": 256
                        }
                      }
                    },
                    "productAttributeId": {
                      "type": "long"
                    },
                    "productId": {
                      "type": "long"
                    },
                    "type": {
                      "type": "long"
                    },
                    "value": {
                      "type": "text",
                      "fields": {
                        "keyword": {
                          "type": "keyword",
                          "ignore_above": 256
                        }
                      }
                    }
                  }
                },
                "id": {
                  "type": "long"
                },
                "lockStock": {
                  "type": "long"
                },
                "lowStock": {
                  "type": "long"
                },
                "pic": {
                  "type": "keyword"
                },
                "price": {
                  "type": "float"
                },
                "productId": {
                  "type": "long"
                },
                "skuCode": {
                  "type": "text",
                  "fields": {
                    "keyword": {
                      "type": "keyword",
                      "ignore_above": 256
                    }
                  }
                },
                "skuTitle": {
                  "type": "text",
                  "fields": {
                    "keyword": {
                      "type": "keyword",
                      "ignore_above": 256
                    }
                  },
                      "analyzer": "ik_max_word"
                },
                "sp1": {
                  "type": "text",
                  "fields": {
                    "keyword": {
                      "type": "keyword",
                      "ignore_above": 256
                    }
                  }
                },
                "sp2": {
                  "type": "text",
                  "fields": {
                    "keyword": {
                      "type": "keyword",
                      "ignore_above": 256
                    }
                  }
                },
                "stock": {
                  "type": "long"
                }
              }
            },
            "sort": {
              "type": "long"
            },
            "stock": {
              "type": "long"
            },
            "subTitle": {
              "type": "text",
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                }
              },
                "analyzer": "ik_max_word"
            }
          }
        }
      }
    }
    

    复杂检索DSL需要考虑的问题

    GET product/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "nested": {
                "path": "skuProductInfos",
                "query": {
                  "match": {
                    "skuProductInfos.skuTitle": "手机"
                  }
                }
              }
            }
          ],
          "filter": [
            {
              "nested": {
                "path": "attrValueList",
                "query": {
                  "bool": {
                    "must": [
                      {
                        "match": {
                          "attrValueList.name": "屏幕尺寸"
                        }
                      },
                      {
                        "match": {
                          "attrValueList.value.keyword": "4.7"
                        }
                      }
                    ]
                  }
                }
              }
            },
            {
              "nested": {
                "path": "attrValueList",
                "query": {
                  "bool": {
                    "must": [
                      {
                        "match": {
                          "attrValueList.name": "网络"
                        }
                      },
                      {
                        "match": {
                          "attrValueList.value.keyword": "4G"
                        }
                      }
                    ]
                  }
                }
              }
            },
            {
              "term": {
                "brandName.keyword": "苹果"
              }
            },
            {
              "term": {
                "productCategoryId": "19"
              }
            },
            {
              "range": {
                "price": {
                  "gte": 5000,
                  "lte": 10000
                }
              }
            }
          ]
        }
      },
      "aggs": {
        "brand_agg": {
          "terms": {
            "field": "brandName.keyword"
          },
          "aggs": {
            "brandId": {
              "terms": {
                "field": "brandId",
                "size": 10
              }
            }
          }
        },
        "category_agg": {
          "terms": {
            "field": "productCategoryName.keyword",
            "size": 10
          }
        },
        "attr_agg": {
          "nested": {
            "path": "attrValueList"
          },
          "aggs": {
            "attrName_agg": {
              "terms": {
                "field": "attrValueList.name",
                "size": 10
              },
              "aggs": {
                "attrValue_agg": {
                  "terms": {
                    "field": "attrValueList.value.keyword",
                    "size": 10
                  }
                }
              }
            }
          }
        }
      },
      "highlight": {
        "pre_tags": "<b style='color:red'>",
        "post_tags": "</b>",
        "fields": {
          "skuProductInfos.skuTitle": {}
        }
      },
      "from": 0,
      "size": 12,
      "sort": [
        {
          "price": {
            "order": "asc"
          }
        },
        {
          "sort":{
            "order": "asc"
          }
        }
      ]
    }
    

    复杂检索参考代码

    public void testSearch(){
        queryDsl(1L,3L,"小米",1);
    }
    
    public void queryDsl(Long brandId,Long productCategoryId,String keyword,int sort){
        SearchSourceBuilder builder = new SearchSourceBuilder();
    
        //1、分页
        builder.from(0).size(10);
    
        //2、搜索
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.matchQuery("name",keyword))
                .should(QueryBuilders.matchQuery("subTitle",keyword))
                .should(QueryBuilders.matchQuery("keywords",keyword));
    
        if (StringUtils.isEmpty(keyword)) {
            builder.query(QueryBuilders.matchAllQuery());
        } else {
            builder.query(boolQuery);
        }
    
        //3、过滤
        if (brandId != null || productCategoryId != null) {
            if (brandId != null) {
                boolQuery.filter(QueryBuilders.termQuery("brandId",brandId));
            }
            if (productCategoryId != null) {
                boolQuery.filter(QueryBuilders.termQuery("productCategoryId",productCategoryId));
            }
            builder.query(boolQuery);
        }
        //排序
        if(sort==1){
            //按新品从新到旧
            builder.sort(SortBuilders.fieldSort("id").order(SortOrder.DESC));
        }else if(sort==2){
            //按销量从高到低
            builder.sort(SortBuilders.fieldSort("sale").order(SortOrder.DESC));
        }else if(sort==3){
            //按价格从低到高
            builder.sort(SortBuilders.fieldSort("price").order(SortOrder.DESC));
        }else if(sort==4){
            //按价格从高到低
            builder.sort(SortBuilders.fieldSort("price").order(SortOrder.ASC));
        }else{
            //按相关度
            builder.sort(SortBuilders.scoreSort().order(SortOrder.DESC));
        }
    
    
        //4、聚合
        //聚合所有品牌
        builder.aggregation(AggregationBuilders.terms("brandNames").field("brandName"));
        //聚合所有分类
        builder.aggregation(AggregationBuilders.terms("productCategoryNames").field("productCategoryName"));
        //聚合所有属性值
    
        NestedAggregationBuilder nestedAggregationBuilder = AggregationBuilders.nested("allAttrValues", "attrValueList")
                .subAggregation(AggregationBuilders.filter("productAttrs", QueryBuilders.termQuery("attrValueList.type", "1")))
                .subAggregation(AggregationBuilders.terms("attrIds")
                        .field("attrValueList.productAttributeId")
                        .subAggregation(AggregationBuilders.terms("attrValues").field("attrValueList.value")
                                .subAggregation(AggregationBuilders.terms("attrNames").field("attrValueList.name"))));
    
        builder.aggregation(nestedAggregationBuilder);
    
        String toString = builder.toString();
        System.out.println("DSL:"+toString);
    }
    

    入参封装

     String  keyword;
    
        String catalog3Id;
    
        String[] attrValues;
    
        int pageNo=1;
    
        int pageSize=20;
    
    

    返回结果封装

     List<SkuInfo> skuInfoList;
    
        long total;
    
        long totalPages;
    
        List<String> attrValueList;
    
    

    ES高级

    嵌套桶

    为了检索嵌套对象,我们在指定mapping的时候应该变为type=nested

    "attrValueList": {
                "type": "nested", 
                "properties": {
                  "id": {
                    "type": "long"
                  },
                  "name": {
                    "type": "keyword"
                  },
                  "productAttributeId": {
                    "type": "long"
                  },
                  "type": {
                    "type": "long"
                  },
                  "value": {
                    "type": "keyword"
                  }
                }
              },
    
    

    ES中文文档

    相关文章

      网友评论

        本文标题:商品检索

        本文链接:https://www.haomeiwen.com/subject/eqdutctx.html