十二、商城业务 | 商品检索

【摘要】商城业务 | 商品检索

前言

173、商城业务-检索服务-搭建页面环境

在zheli-search.pom添加依赖。

1
2
3
4
5
6
7
8
9
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>

搜索页/html拷贝到search服务的resources/templates下。其他静态资源放置在nginx/html/static/search中。

修改host文件,添加search.zhelimall.com 127.0.0.1

修改nginx/conf/conf.d/zhelimaill.conf中的server_name

1
2
3
4
5
server{
# ...
server_name zhelimall.com *.zhelimall.com;
# ...
}

配置网关服务

1
2
3
4
5
6
7
8
9
- id: zhelimall_host_route
uri: lb://zheli-product
predicates:
- Host=zhelimall.com

- id: zhelimall_search_route
uri: lb://zheli-search
predicates:
- Host=search.zhelimall.com

重启网关服务、搜索服务和nginx。访问search.zhelimall.com就可以看到对应的页面了。

配置完成后Nginx的转发效果如下所示。

174、商城业务-检索服务-调整页面跳转

前面搭建好了检索的页面,接下来就来梳理一下整个商城的检索逻辑。

引入devtools热启动,关闭thymeleaf缓存功能。

application.properties

1
spring.thymeleaf.cache=false

通过现有的分析,我们在首页有两处会进入搜索页面。第一处是通过点击分类,第二处是搜索框。

点击搜索跳转到的是http://search.zhelimall.com/list.html?catalog3Id=225

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.aiz.zhelimall.search.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class SearchController {

@GetMapping("/list.html")
public String listPage(){
return "index";
}

}

175、商城业务-检索服务-检索查询参数模型分析抽取

检索业务分析

商品检索三个入口:

  • 选择分类进入商品检索

  • 输入检索关键字展示检索页

  • 选择筛选条件进入

检索条件&排序条件

  • 全文检索:skuTitle -> keyword
  • 排序:saleCount(销量)、hotScore(热度分)、skuPrice(价格)
  • 过滤:hasStock、skuPrice区间、brandId、catalog3Id、attrs
  • 聚合:attrs

完整查询参数

  • keyword=小米 &sort=saleCount_desc/asc&hasStock=0/1&skuPrice=400_1900&brandId=1&catalog3Id=1&attrs=1_3G:4G:5G&attrs=2_骁龙845&attrs=4_高清屏

检索语句构建

结果提取封装

检索条件分析。

SearchParam.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* @Description 封装页面所有可能传递过来的查询条件
*/
@Data
public class SearchParam {
/**
* 检索关键字
*/
private String keyword;//页面传递过来的全文匹配关键字
//三级分类ID
private Long catalog3Id;

/**
* sort=saleCount_asc/desc
* sort=hotScore_asc/desc
* sort=skuPrice_asc/desc
*/
private String sort;//排序条件(saleCount(销量)、hotScore(热度分)、skuPrice(价格))

/**
* 好多的过滤条件
* hasStock(是否有货)、skuPrice区间、brandId、catalog3Id、attrs
* hasStock=0/1
* skuPrice=1_500/_500/500
* brandId=1
* attrs=2_5寸:6寸
*/
//是否有库存(0表示无库存,1表示有库存)
private Integer hasStock;
//价格区间查询
private String skuPrice;
//按照品牌进行查询,可以多选
private List<Long> brandId;
//按照属性进行筛选
private List<String> attrs;

//页码
private Integer pageNum = 1;
}

SearchController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Controller
public class SearchController {

@Autowired
MallSearchService mallSearchService;

/**
* 自动将页面提交过来的所有请求查询参数封装成指定的对象
* @param searchParam
* @return
*/
@GetMapping("/list.html")
public String listPage(SearchParam searchParam){
Object result = mallSearchService.search(searchParam);
return "index";
}

}

176、商城业务-检索服务-检索返回结果模型分析抽取

前面已经把页面提交过来的所有请求查询参数封装成指定的对象,这部分需要分析检索返回结果的模型。观察页面可以知道这边返回的应该是所有的商品信息。由于我们是在es中检索的,所以我们查到的也是es中商品的模型数据。

SearchResult.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
* @ClassName SearchResult
* @Description 返回给页面的所有信息
*/
@Data
public class SearchResult {

/**
* 查询到的所有商品信息
*/
private List<SkuEsModel> products;

/**
* 以下是分页信息
*/
private Integer pageNum;//当前页码
private Long total;//总记录数
private Integer totalPages;//总页码

/**
* 当前查询到的结果,所有涉及到的品牌
*/
private List<BrandVo> brands;

/**
* 当前查询到的结果,所有涉及到的分类
*/
private List<CatalogVo> catalogs;

/**
* 当前查询到的结果,所有涉及到的所有属性
*/
private List<AttrVo> attrs;

//以上是返回给页面的所有信息


@Data
public static class BrandVo{
private Long brandId;
private String brandName;
private String brandImg;
}

@Data
public static class CatalogVo{
private Long catalogId;
private String catalogName;
}

@Data
public static class AttrVo{
private Long attrId;
private String attrName;
private List<String> attrValue;
}

}

177、商城业务-检索服务-检索DSL测试-查询部分

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
GET product/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"skuTitle": "荣耀"
}
}
],
"filter": [
{
"term": {
"catalogId": "225"
}
},
{
"terms": {
"brandId": [
"1",
"2",
"9"
]
}
},
{
"term": {
"attrs.attrId": "1"
}
},
{
"term":{
"hasStock":{
"value":"false"
}
}
},
{
"range":{
"skuPrice":{
"gte":0,
"lte":6000
}
}
}
]
}
},
"sort": [
{
"skuPrice": {
"order": "desc"
}
}
],
"from": 0,
"size": 2,
"highlight": {
"fields": {"skuTitle": {}},
"pre_tags": "<b style='color:red'>",
"post_tags": "</b>"
}
}

查询结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 15,
"relation" : "eq"
},
"max_score" : null,
"hits" : [
{
"_index" : "product",
"_type" : "_doc",
"_id" : "9",
"_score" : null,
"_source" : {
"attrs" : [
{
"attrId" : 1,
"attrName" : "入网型号",
"attrValue" : "BMH-AN10"
},
{
"attrId" : 3,
"attrName" : "上市年份",
"attrValue" : "2019"
},
{
"attrId" : 4,
"attrName" : "产品名称",
"attrValue" : "荣耀30pro"
},
{
"attrId" : 2,
"attrName" : "机身重量",
"attrValue" : "185g"
},
{
"attrId" : 6,
"attrName" : "GPU型号",
"attrValue" : "Mali-G77"
}
],
"brandId" : 2,
"brandImg" : "https://zheli-mall.oss-cn-shanghai.aliyuncs.com/2020-07-05/de569ad1-7ecf-4752-8d26-0dc64983bdb3_huawei.png",
"brandName" : "华为",
"catalogId" : 225,
"catalogName" : "手机",
"hasStock" : false,
"hotScore" : 0,
"saleCount" : 0,
"skuId" : 9,
"skuImg" : "https://zheli-mall.oss-cn-shanghai.aliyuncs.com/2020-07-22/cc1ca9dc-9ebc-40e2-884f-ef91fe540b98_d511faab82abb34b.jpg",
"skuPrice" : 2799.0,
"skuTitle" : "荣耀3 翡翠绿 26G+256G 256G",
"spuId" : 7
},
"highlight" : {
"skuTitle" : [
"<b style='color:red'>荣</b><b style='color:red'>耀</b>3 翡翠绿 26G+256G 256G"
]
},
"sort" : [
2799.0
]
},
{
"_index" : "product",
"_type" : "_doc",
"_id" : "10",
"_score" : null,
"_source" : {
"attrs" : [
{
"attrId" : 1,
"attrName" : "入网型号",
"attrValue" : "BMH-AN10"
},
{
"attrId" : 3,
"attrName" : "上市年份",
"attrValue" : "2019"
},
{
"attrId" : 4,
"attrName" : "产品名称",
"attrValue" : "荣耀30pro"
},
{
"attrId" : 2,
"attrName" : "机身重量",
"attrValue" : "185g"
},
{
"attrId" : 6,
"attrName" : "GPU型号",
"attrValue" : "Mali-G77"
}
],
"brandId" : 2,
"brandImg" : "https://zheli-mall.oss-cn-shanghai.aliyuncs.com/2020-07-05/de569ad1-7ecf-4752-8d26-0dc64983bdb3_huawei.png",
"brandName" : "华为",
"catalogId" : 225,
"catalogName" : "手机",
"hasStock" : false,
"hotScore" : 0,
"saleCount" : 0,
"skuId" : 10,
"skuImg" : "https://zheli-mall.oss-cn-shanghai.aliyuncs.com/2020-07-22/0b49f2fa-5841-4da6-8551-a5fcac7f71c5_23d9fbb256ea5d4a.jpg",
"skuPrice" : 2799.0,
"skuTitle" : "荣耀3 翡翠绿 26G+256G 128G",
"spuId" : 7
},
"highlight" : {
"skuTitle" : [
"<b style='color:red'>荣</b><b style='color:red'>耀</b>3 翡翠绿 26G+256G 128G"
]
},
"sort" : [
2799.0
]
}
]
}
}

178、商城业务-检索服务-检索DSL测试-聚合部分

重新定义文档,之后数据迁移。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
"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"
}
}
}
}

聚合部分。注意:attr_agg部分没调试成功,暂时忽略。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
GET product/_search
{
"query": {
"match_all": {}
},
"aggs": {
"brand_agg": {
"terms": {
"field": "brandId",
"size": 10
},
"aggs": {
"brand_name_agg": {
"terms": {
"field": "brandName.keyword",
"size": 10
}
},
"brand_img_agg":{
"terms": {
"field": "brandImg.keyword",
"size": 10
}
}
}
},
"catelog_agg":{
"terms": {
"field": "catalogId",
"size": 10
},
"aggs": {
"catelog_name_agg": {
"terms": {
"field": "catalogName.keyword",
"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
}
}
}
}
}
}
}
}

179、商城业务-检索服务-SearchRequest构建-检索

180、商城业务-检索服务-SearchRequest构建-排序、分页、高亮&测试

访问http://search.zhelimall.com/list.html?keyword=测试一下。控制台打印如下信息:

1
构建的DSL语句{"from":0,"size":2,"query":{"bool":{"filter":[{"term":{"hasStock":{"value":true,"boost":1.0}}}],"adjust_pure_negative":true,"boost":1.0}}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"from": 0,
"size": 2,
"query": {
"bool": {
"filter": [{
"term": {
"hasStock": {
"value": true,
"boost": 1.0
}
}
}],
"adjust_pure_negative": true,
"boost": 1.0
}
}
}

181、商城业务-检索服务-SearchRequest构建-聚合

182、商城业务-检索服务-SearchResponse分析&封装

183、商城业务-检索服务-验证结果封装正确性

184、商城业务-检索服务-页面基本数据渲染

185、商城业务-检索服务-页面筛选条件渲染

186、商城业务-检索服务-页面分页数据渲染

187、商城业务-检索服务-页面排序功能

188、商城业务-检索服务-页面排序字段回显

189、商城业务-检索服务-页面价格区间搜索

190、商城业务-检索服务-面包屑导航

191、商城业务-检索服务-条件删除与URL编码问题

192、商城业务-检索服务-条件筛选联动

评论