it_lv 3 هفته پیش
والد
کامیت
4c4c328ad5
2فایلهای تغییر یافته به همراه247 افزوده شده و 267 حذف شده
  1. 4 53
      听书软件环境安装.md
  2. 243 214
      第4章 检索模块.md

+ 4 - 53
听书软件环境安装.md

@@ -297,7 +297,7 @@ docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
 --net elastic \
 --restart=always \
 -e "discovery.type=single-node" \
--e ES_JAVA_OPTS="-Xms1024m -Xmx1024m" \
+-e ES_JAVA_OPTS="-Xms512m -Xmx512m" \
 -v /opt/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
 -v /opt/elasticsearch/data:/usr/share/elasticsearch/data \
 -v /opt/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
@@ -364,63 +364,14 @@ output {
 第三步:创建容器
 
 ```纯文本
-docker run --name gmalldocker_logstash -p 5044:5044 \
+docker run --name logstash -p 5044:5044 \
+--net elastic \
 --restart=always \
---link gmalldocker_elasticsearch:es \
+--link elasticsearch:es \
 -v /mydata/logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf \
 -d logstash:8.5.0
 ```
 
-安装Filebeat
-
-第一步:授权
-
-chmod 777 -R /var/log/messages
-
-第二步:启动日志收集器
-
-```text
-docker run -d \
-  --name=filebeat \
-  --restart=always \
-  -v filebeat-conf:/usr/share/filebeat \
-  -v /var/log/messages:/var/log/messages \
-  --link 1833f6a65c2a:gmalldocker_elasticsearch \
-  elastic/filebeat:7.8.0
-  
-  1833f6a65c2a: es容器的ID
-```
-
-第三步:修改配置文件:
-
-```纯文本
-进入到目录:
-cd /var/lib/docker/volumes/filebeat-conf/_data
-修改配置文件
-vim filebeat.yml
-内容如下
-filebeat.inputs:
-- type: log
-  enabled: true
-  paths:
-    - /var/log/messages
-filebeat.config:
-  modules:
-    path: ${path.config}/modules.d/*.yml
-    reload.enabled: false
-
-processors:
-  - add_cloud_metadata: ~
-  - add_docker_metadata: ~
-
-output.elasticsearch:
-  hosts: '192.168.200.128:9200'
-  indices:
-   - index: "filebeat-%{+yyyy.MM.dd}"
-```
-
-
-
 ## 9安装kibana
 
 第一步:拉取镜像

+ 243 - 214
第4章 检索模块.md

@@ -1704,15 +1704,14 @@ POST album_info/_search
 
 ```java
 /**
- * 站内条件检索专辑接口
- *
+ * 站内搜索
  * @param albumIndexQuery
  * @return
  */
-@Operation(summary = "站内条件检索专辑接口")
+@Operation(summary = "站内搜索")
 @PostMapping("/albumInfo")
-public Result<AlbumSearchResponseVo> search(@RequestBody AlbumIndexQuery albumIndexQuery) {
-    AlbumSearchResponseVo vo = searchService.search(albumIndexQuery);
+public Result<AlbumSearchResponseVo> search(@RequestBody AlbumIndexQuery albumIndexQuery){
+    AlbumSearchResponseVo vo  = searchService.search(albumIndexQuery);
     return Result.ok(vo);
 }
 ```
@@ -1721,27 +1720,26 @@ public Result<AlbumSearchResponseVo> search(@RequestBody AlbumIndexQuery albumIn
 
 ```java
 /**
- * 根据条件检索ElasticSearch专辑索引库
- * @param albumIndexQuery 查询条件
+ * 站内搜索
+ * @param albumIndexQuery
  * @return
  */
 AlbumSearchResponseVo search(AlbumIndexQuery albumIndexQuery);
 
-
 /**
- * 基于检索条件对象封装检索请求对象(封装完整DSL语句)
- * @param albumIndexQuery
+ * 基于查询条件封装ES检索DSL语句
+ * @param albumIndexQuery 查询条件
  * @return
  */
 SearchRequest buildDSL(AlbumIndexQuery albumIndexQuery);
 
 /**
- * 解析ES检索结果
+ * 解析ES响应结果
  * @param searchResponse
  * @param albumIndexQuery
  * @return
  */
-AlbumSearchResponseVo parseSearchResult(SearchResponse<AlbumInfoIndex> searchResponse, AlbumIndexQuery albumIndexQuery);
+AlbumSearchResponseVo parseResult(SearchResponse<AlbumInfoIndex> searchResponse, AlbumIndexQuery albumIndexQuery);
 ```
 
 **SearchServiceImpl实现类**:
@@ -1751,29 +1749,26 @@ AlbumSearchResponseVo parseSearchResult(SearchResponse<AlbumInfoIndex> searchRes
 private ElasticsearchClient elasticsearchClient;
 
 
-//专辑索引库名称
-private static final String INDE_NAME = "album_info";
-
 /**
- * 整体采用传统写法,局部采用Lambda表达方式
- * 根据条件检索ElasticSearch专辑索引库
+ * 站内搜索
  *
- * @param albumIndexQuery 查询条件
+ * @param albumIndexQuery
  * @return
  */
 @Override
 public AlbumSearchResponseVo search(AlbumIndexQuery albumIndexQuery) {
     try {
-        //1.基于查询条件封装检索请求对象
+        //一、构建完整检索请求对象:包含完整DSL语句请求体参数
         SearchRequest searchRequest = this.buildDSL(albumIndexQuery);
         System.err.println("本次检索DSL:");
-        System.err.println(searchRequest);
-        //2.执行索引库检索
+        System.out.println(searchRequest);
+        //二、执行检索
         SearchResponse<AlbumInfoIndex> searchResponse = elasticsearchClient.search(searchRequest, AlbumInfoIndex.class);
-        //3.解析解析ES检索结果
-        return this.parseSearchResult(searchResponse, albumIndexQuery);
-    } catch (Exception e) {
-        log.error("[检索服务]站内搜索异常:{}", e);
+
+        //三、解析ES响应结果
+        return this.parseResult(searchResponse, albumIndexQuery);
+    } catch (IOException e) {
+        log.error("执行检索失败", e);
         throw new RuntimeException(e);
     }
 }
@@ -1782,94 +1777,111 @@ public AlbumSearchResponseVo search(AlbumIndexQuery albumIndexQuery) {
 **封装站内专辑检索DSL请求**
 
 ```java
+private static final String INDEX_NAME = "albuminfo";
+
 /**
- * 基于检索条件对象封装检索请求对象(封装完整DSL语句)
+ * 整体看采用传统方式,局部采用Lambda简化开发
+ * 基于查询条件封装ES检索DSL语句
  *
- * @param albumIndexQuery
+ * @param albumIndexQuery 查询条件
  * @return
  */
 @Override
 public SearchRequest buildDSL(AlbumIndexQuery albumIndexQuery) {
-    //1.创建检索请求构建器对象
+    //1.创建检索构建器对象 封装 请求地址中:index 索引库名称
     SearchRequest.Builder builder = new SearchRequest.Builder();
-    //2.设置DSL中各项请求体参数信息:分页、高亮、排序、条件、过滤
-    //2.1 设置请求路径中检索:索引库名称
-    builder.index(INDE_NAME);
-    //2.2 设置请求体参数中"query"查询条件
+    builder.index(INDEX_NAME);
+    //2.设置查询条件:请求体参数query
     String keyword = albumIndexQuery.getKeyword();
-    //2.2.1 创建组合三大查询条件bool查询对象
+    //2.0 创建bool查询条件:用于封装所有查询条件
     BoolQuery.Builder allConditionBoolQueryBuilder = new BoolQuery.Builder();
-    //2.2.2 设置查询条件-关键字(全文查询专辑标题)
+    //2.1 条件1:关键字 采用must 有算分机制按相关性返回
     if (StringUtils.isNotBlank(keyword)) {
-        allConditionBoolQueryBuilder.must(m->m.match(m1 -> m1.field("albumTitle").query(keyword)));
+        allConditionBoolQueryBuilder.must(m -> m.match(m1 -> m1.field("albumTitle").query(keyword)));
     }
-    //2.2.3 设置过滤条件-分类
+    //2.2 条件2:一二三级分类ID 采用filter 有缓存机制
+    //2.2.1. 封装1级分类ID查询条件
     Long category1Id = albumIndexQuery.getCategory1Id();
     if (category1Id != null) {
         allConditionBoolQueryBuilder.filter(f -> f.term(t -> t.field("category1Id").value(category1Id)));
     }
+    //2.2.2. 封装2级分类ID查询条件
     Long category2Id = albumIndexQuery.getCategory2Id();
     if (category2Id != null) {
         allConditionBoolQueryBuilder.filter(f -> f.term(t -> t.field("category2Id").value(category2Id)));
     }
+    //2.2.3. 封装3级分类ID查询条件
     Long category3Id = albumIndexQuery.getCategory3Id();
     if (category3Id != null) {
         allConditionBoolQueryBuilder.filter(f -> f.term(t -> t.field("category3Id").value(category3Id)));
     }
-    //2.2.4 设置过滤条件-标签 可能提交多组标签过滤条件 一组标签条件形式=标签ID:标签值ID
+    //2.3 条件3:多组标签List集合 每组标签形式=标签ID:标签值ID
     List<String> attributeList = albumIndexQuery.getAttributeList();
-    if (CollectionUtil.isNotEmpty(attributeList)) {
-        for (String attribute : attributeList) {
-            //2.2.4.1 每循环一次设置一组标签过滤条件 标签ID:标签值ID
-            String[] split = attribute.split(":");
+    //2.4 每遍历一组标签过滤条件,设置一个Nested查询
+    if (CollUtil.isNotEmpty(attributeList)) {
+        for (String s : attributeList) {
+            String[] split = s.split(":");
             if (split != null && split.length == 2) {
-                allConditionBoolQueryBuilder.filter(f -> f.nested(
-                        n -> n.path("attributeValueIndexList")
-                                .query(q -> q.bool(
-                                        b -> b.must(m -> m.term(t -> t.field("attributeValueIndexList.attributeId").value(split[0])))
+                allConditionBoolQueryBuilder
+                        .filter(f -> f.nested(
+                                n -> n.path("attributeValueIndexList")
+                                        .query(q -> q.bool(b -> b.must(m -> m.term(t -> t.field("attributeValueIndexList.attributeId").value(split[0])))
                                                 .must(m -> m.term(t -> t.field("attributeValueIndexList.valueId").value(split[1])))
-                                ))
-                ));
+                                        ))
+                        ));
             }
         }
     }
+
     builder.query(allConditionBoolQueryBuilder.build()._toQuery());
-    //2.3 设置请求体参数中"from,size"分页信息
-    int from = (albumIndexQuery.getPageNo() - 1) * albumIndexQuery.getPageSize();
-    builder.from(from).size(albumIndexQuery.getPageSize());
-    //2.4 设置请求体参数中"sort"排序
+    //builder.query();
+    //3.设置分页:请求体参数from size
+    Integer pageNo = albumIndexQuery.getPageNo();
+    Integer pageSize = albumIndexQuery.getPageSize();
+    int from = (pageNo - 1) * pageSize;
+    builder.from(from).size(pageSize);
+
+    //4.设置排序:请求体参数sort
+    //4.1 前后端约定 如果需要排序提交参数order值=排序字段(1,2,3):排序方式(asc,desc)
     String order = albumIndexQuery.getOrder();
-    //2.4.1 获取前端提交排序参数取值 形式=1:desc
     if (StringUtils.isNotBlank(order)) {
+        //4.2 获取排序字段以及排序方式
         String[] split = order.split(":");
         if (split != null && split.length == 2) {
-            //2.4.2 获取排序字段
-            String orderField = "";
+            String sortField = "";
             switch (split[0]) {
                 case "1":
-                    orderField = "hotScore";
+                    sortField = "hotScore";
                     break;
                 case "2":
-                    orderField = "playStatNum";
+                    sortField = "playStatNum";
                     break;
                 case "3":
-                    orderField = "createTime";
+                    sortField = "createTime";
                     break;
             }
-            //2.4.3 获取排序方式
-            String orderDes = split[1];
-            String finalOrderField = orderField;
-            builder.sort(s -> s.field(f -> f.field(finalOrderField).order("asc".equals(orderDes) ? SortOrder.Asc : SortOrder.Desc)));
+            String direction = split[1];
+            //4.3 动态设置排序
+            SortOrder sortOrder = "asc".equals(direction) ? SortOrder.Asc : SortOrder.Desc;
+            String finalSortField = sortField;
+            builder.sort(s -> s.field(f -> f.field(finalSortField).order(sortOrder)));
         }
     }
-    //2.5 设置请求体参数中"highlight"高亮
+
+    //5.设置高亮:请求体参数highlight 前提条件:用户采用关键字全文查询text字段
     if (StringUtils.isNotBlank(keyword)) {
         builder.highlight(h -> h.fields("albumTitle", f -> f.preTags("<font style='color:red'>").postTags("</font>")));
     }
-    //2.6 设置请求体参数中"_source"指定查询字段
-    builder.source(s -> s.filter(f -> f.includes("id", "albumTitle", "albumIntro", "coverUrl", "includeTrackCount", "playStatNum", "createTime", "payType")));
 
-    //3.基于构建器对象返回检索请求对象
+    //6.设置响应字段:请求体参数_source
+    builder.source(s -> s.filter(f -> f.excludes("attributeValueIndexList",
+            "hotScore",
+            "commentStatNum",
+            "buyStatNum",
+            "subscribeStatNum",
+            "announcerName")));
+
+    //7.基于构建器对象返回实际检索对象
     return builder.build();
 }
 ```
@@ -1878,47 +1890,49 @@ public SearchRequest buildDSL(AlbumIndexQuery albumIndexQuery) {
 
 ```java
 /**
- * 解析ES检索结果
+ * 解析ES响应结果
  *
- * @param searchResponse
- * @param albumIndexQuery
+ * @param searchResponse  ES响应对象
+ * @param albumIndexQuery 查询条件
  * @return
  */
 @Override
-public AlbumSearchResponseVo parseSearchResult(SearchResponse<AlbumInfoIndex> searchResponse, AlbumIndexQuery albumIndexQuery) {
-    //1.创建响应VO对象
+public AlbumSearchResponseVo parseResult(SearchResponse<AlbumInfoIndex> searchResponse, AlbumIndexQuery albumIndexQuery) {
+    //1.创建响应结果对象
     AlbumSearchResponseVo vo = new AlbumSearchResponseVo();
-
-    //2.封装VO中四个分页相关信息
+    //2.封装VO中分页四项信息
     Integer pageNo = albumIndexQuery.getPageNo();
     Integer pageSize = albumIndexQuery.getPageSize();
+    //2.1 获取ES结果中总记录数
+    HitsMetadata<AlbumInfoIndex> hits = searchResponse.hits();
+    long total = hits.total().value();
+    //2.2 计算总页数  页大小=10  总计:101
+    long totalPages = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
     vo.setPageNo(pageNo);
     vo.setPageSize(pageSize);
-    //2.1 解析ES获取命中记录数
-    long total = searchResponse.hits().total().value();
     vo.setTotal(total);
-    //2.2 根据总记录数及页大小计算总页码
-    long totalPages = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
     vo.setTotalPages(totalPages);
 
-    //3.封装Vo中检索到文档数据(记得处理高亮)
-    List<Hit<AlbumInfoIndex>> hitList = searchResponse.hits().hits();
-    if (CollectionUtil.isNotEmpty(hitList)) {
-        //3.1 遍历命中记录对象得到Hit对象中中_source(专辑对象)
-        List<AlbumInfoIndexVo> list = hitList.stream()
+    //3.封装Vo中专辑列表
+    List<Hit<AlbumInfoIndex>> hitsList = hits.hits();
+    if (CollUtil.isNotEmpty(hitsList)) {
+        List<AlbumInfoIndexVo> infoIndexVoList = hitsList
+                .stream()
                 .map(hit -> {
+                    //3.1 获取命中文档原数据
                     AlbumInfoIndex albumInfoIndex = hit.source();
-                    //3.2 处理高亮
-                    Map<String, List<String>> highlightMap = hit.highlight();
-                    if (CollectionUtil.isNotEmpty(highlightMap)) {
-                        String highlightText = highlightMap.get("albumTitle").get(0);
-                        albumInfoIndex.setAlbumTitle(highlightText);
+                    //3.2 处理高亮片段
+                    Map<String, List<String>> highlight = hit.highlight();
+                    if (CollUtil.isNotEmpty(highlight)) {
+                        String albumTitleHightLight = highlight.get("albumTitle").get(0);
+                        albumInfoIndex.setAlbumTitle(albumTitleHightLight);
                     }
+                    //3.3响应VO
                     return BeanUtil.copyProperties(albumInfoIndex, AlbumInfoIndexVo.class);
                 }).collect(Collectors.toList());
-        vo.setList(list);
+        vo.setList(infoIndexVoList);
     }
-    //4.响应VO
+    //x.响应结果VO对象
     return vo;
 }
 ```
@@ -1943,14 +1957,14 @@ public AlbumSearchResponseVo parseSearchResult(SearchResponse<AlbumInfoIndex> se
 
 ```java
 /**
- * 根据1级分类ID查询置顶3级分类列表
+ * 根据一级分类Id查询置顶7个三级分类列表
  * @param category1Id
  * @return
  */
-@Operation(summary = "根据1级分类ID查询置顶3级分类列表")
+@Operation(summary = "根据一级分类Id查询置顶7个三级分类列表")
 @GetMapping("/category/findTopBaseCategory3/{category1Id}")
-public Result<List<BaseCategory3>> getTopBaseCategory3(@PathVariable Long category1Id){
-    List<BaseCategory3> list = baseCategoryService.getTopBaseCategory3(category1Id);
+public Result<List<BaseCategory3>> findTopBaseCategory3(@PathVariable Long category1Id) {
+    List<BaseCategory3> list = baseCategoryService.findTopBaseCategory3(category1Id);
     return Result.ok(list);
 }
 ```
@@ -1959,47 +1973,42 @@ public Result<List<BaseCategory3>> getTopBaseCategory3(@PathVariable Long catego
 
 ```java
 /**
- * 根据1级分类ID查询置顶3级分类列表
+ * 根据一级分类Id查询置顶7个三级分类列表
  * @param category1Id
  * @return
  */
-List<BaseCategory3> getTopBaseCategory3(Long category1Id);
+List<BaseCategory3> findTopBaseCategory3(Long category1Id);
 ```
 
 **BaseCategoryServiceImpl实现类**
 
 ```java
 /**
- * 根据1级分类ID查询置顶3级分类列表
+ * 根据一级分类Id查询置顶7个三级分类列表
  *
  * @param category1Id
  * @return
  */
 @Override
-public List<BaseCategory3> getTopBaseCategory3(Long category1Id) {
-    //1.根据1级分类ID得到二级分类列表(获取二级分类ID列表)
-    LambdaQueryWrapper<BaseCategory2> category2LambdaQueryWrapper = new LambdaQueryWrapper<>();
-    category2LambdaQueryWrapper.eq(BaseCategory2::getCategory1Id, category1Id);
-    category2LambdaQueryWrapper.select(BaseCategory2::getId);
-    List<BaseCategory2> baseCategory2List = baseCategory2Mapper.selectList(category2LambdaQueryWrapper);
-    if (CollectionUtil.isNotEmpty(baseCategory2List)) {
-        //2.根据二级分类ID列表得到置顶三级分类
-        //2.1 获取所有2级分类ID
-        List<Long> category2IdList = baseCategory2List
-                .stream()
-                .map(BaseCategory2::getId)
-                .collect(Collectors.toList());
-        //2.2 构建查询三级分类条件
-        LambdaQueryWrapper<BaseCategory3> baseCategory3LambdaQueryWrapper = new LambdaQueryWrapper<>();
-        baseCategory3LambdaQueryWrapper.eq(BaseCategory3::getIsTop, 1);
-        baseCategory3LambdaQueryWrapper.in(BaseCategory3::getCategory2Id, category2IdList);
-        baseCategory3LambdaQueryWrapper.orderByAsc(BaseCategory3::getOrderNum);
-        baseCategory3LambdaQueryWrapper.last("LIMIT 7");
-        baseCategory3LambdaQueryWrapper.select(BaseCategory3::getId, BaseCategory3::getName, BaseCategory3::getCategory2Id);
-        //2.3 查询得到7个置顶三级分类
-        List<BaseCategory3> list = baseCategory3Mapper.selectList(baseCategory3LambdaQueryWrapper);
-        return list;
+public List<BaseCategory3> findTopBaseCategory3(Long category1Id) {
+    //1.根据1级分类ID查询该1级分类下二级分类ID列表
+    List<BaseCategory2> baseCategory2List = baseCategory2Mapper.selectList(
+            new LambdaQueryWrapper<BaseCategory2>()
+                    .eq(BaseCategory2::getCategory1Id, category1Id)
+                    .select(BaseCategory2::getId)
+    );
+    if (CollUtil.isNotEmpty(baseCategory2List)) {
+        List<Long> category2IdList = baseCategory2List.stream()
+                .map(BaseCategory2::getId).collect(Collectors.toList());
+        //2.根据二级分类ID列表查询置顶前7个个三级分类列表
+        LambdaQueryWrapper<BaseCategory3> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.in(BaseCategory3::getCategory2Id, category2IdList);
+        queryWrapper.eq(BaseCategory3::getIsTop, 1);
+        queryWrapper.orderByAsc(BaseCategory3::getOrderNum);
+        queryWrapper.last("limit 7");
+        return baseCategory3Mapper.selectList(queryWrapper);
     }
+
     return null;
 }
 ```
@@ -2016,13 +2025,13 @@ public List<BaseCategory3> getTopBaseCategory3(Long category1Id) {
 
 ```java
 /**
- * 查询当前1级分类下包含子分类(二三级分类)
+ * 查询1级分类下包含所有二级以及三级分类
  * @param category1Id
- * @return {"categoryId":1,"categoryName":"音乐",categoryChild:[{"categoryId":101,"categoryName":"音乐音效",categoryChild:[{..}]}]}
+ * @return
  */
-@Operation(summary = "查询当前1级分类下包含子分类(二三级分类)")
+@Operation(summary = "查询1级分类下包含所有二级以及三级分类")
 @GetMapping("/category/getBaseCategoryList/{category1Id}")
-public Result<JSONObject> getBaseCategoryListByCategory1Id(@PathVariable Long category1Id){
+public Result<JSONObject> getBaseCategoryListByCategory1Id(@PathVariable Long category1Id) {
     JSONObject jsonObject = baseCategoryService.getBaseCategoryListByCategory1Id(category1Id);
     return Result.ok(jsonObject);
 }
@@ -2032,9 +2041,9 @@ public Result<JSONObject> getBaseCategoryListByCategory1Id(@PathVariable Long ca
 
 ```java
 /**
- * 查询当前1级分类下包含子分类(二三级分类)
+ * 查询1级分类下包含所有二级以及三级分类
  * @param category1Id
- * @return {"categoryId":1,"categoryName":"音乐",categoryChild:[{"categoryId":101,"categoryName":"音乐音效",categoryChild:[{..}]}]}
+ * @return 一级分类对象
  */
 JSONObject getBaseCategoryListByCategory1Id(Long category1Id);
 ```
@@ -2043,49 +2052,63 @@ JSONObject getBaseCategoryListByCategory1Id(Long category1Id);
 
 ```java
 /**
- * 查询当前1级分类下包含子分类(二三级分类)
+ * 查询1级分类下包含所有二级以及三级分类
  *
  * @param category1Id
- * @return {"categoryId":1,"categoryName":"音乐",categoryChild:[{"categoryId":101,"categoryName":"音乐音效",categoryChild:[{..}]}]}
+ * @return 一级分类对象
  */
 @Override
 public JSONObject getBaseCategoryListByCategory1Id(Long category1Id) {
-    //1.根据1级分类ID查询分类视图得到“1级”分类列表  封装1级分类对象
-    LambdaQueryWrapper<BaseCategoryView> queryWrapper = new LambdaQueryWrapper<>();
-    queryWrapper.eq(BaseCategoryView::getCategory1Id, category1Id);
-    List<BaseCategoryView> category1List = baseCategoryViewMapper.selectList(queryWrapper);
-    if (CollectionUtil.isNotEmpty(category1List)) {
-        String category1Name = category1List.get(0).getCategory1Name();
-        //1.1 封装1级分类对象
+    //1.处理1级分类
+    //1.1 根据1级分类ID查询分类视图得到所有"1级分类"列表
+    List<BaseCategoryView> baseCategory1List = baseCategoryViewMapper.selectList(
+            new LambdaQueryWrapper<BaseCategoryView>()
+                    .eq(BaseCategoryView::getCategory1Id, category1Id)
+    );
+    if (CollUtil.isNotEmpty(baseCategory1List)) {
+        BaseCategoryView baseCategoryView = baseCategory1List.get(0);
+        //1.2 创建1级分类JSON对象
         JSONObject jsonObject1 = new JSONObject();
-        jsonObject1.put("categoryId", category1Id);
-        jsonObject1.put("categoryName", category1Name);
-        //2.处理二级分类
-        List<JSONObject> jsonObject2List = new ArrayList<>();
-        //2.1 对"1级"分类列表进行按2级分类ID分组
-        Map<Long, List<BaseCategoryView>> map2 = category1List
+        //1.2.1 封装1级分类ID
+        jsonObject1.put("categoryId", baseCategoryView.getCategory1Id());
+        //1.2.2 封装1级分类名称
+        jsonObject1.put("categoryName", baseCategoryView.getCategory1Name());
+
+        //2.处理2级分类
+        //2.1 对"1级分类列表"按二级分类ID进行分组,得到Map
+        Map<Long, List<BaseCategoryView>> map2 = baseCategory1List
                 .stream()
                 .collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
-        //2.2 遍历"2级"分类Map
+
+        //2.2 遍历Map,创建二级分类JSON对象集合
+        List<JSONObject> jsonObject2List = new ArrayList<>();
         for (Map.Entry<Long, List<BaseCategoryView>> entry2 : map2.entrySet()) {
+            //2.2.1 创建二级分类JSON对象
+            JSONObject jsonObject2 = new JSONObject();
+            //2.2.2 封装二级分类ID
             Long category2Id = entry2.getKey();
+            //2.2.3 封装二级分类名称
             String category2Name = entry2.getValue().get(0).getCategory2Name();
-            //2.3 封装2级分类JSON对象
-            JSONObject jsonObject2 = new JSONObject();
-            jsonObject2.put("categoryId", category2Id);
+            jsonObject2.put("categoryId", category1Id);
             jsonObject2.put("categoryName", category2Name);
-            //3.处理三级分类
+            //3.处理3级分类
+            //3.1 创建3级分类JSON对象集合
             List<JSONObject> jsonObject3List = new ArrayList<>();
-            for (BaseCategoryView baseCategoryView : entry2.getValue()) {
+            //3.2 遍历"2级分类列表",封装三级分类对象
+            for (BaseCategoryView categoryView : entry2.getValue()) {
+                //3.2.1 创建3级分类JSON对象
                 JSONObject jsonObject3 = new JSONObject();
-                jsonObject3.put("categoryId", baseCategoryView.getCategory3Id());
-                jsonObject3.put("categoryName", baseCategoryView.getCategory3Name());
+                //3.2.2 封装3级分类ID
+                jsonObject3.put("categoryId", categoryView.getCategory3Id());
+                //3.2.3 封装3级分类名称
+                jsonObject3.put("categoryName", categoryView.getCategory3Name());
                 jsonObject3List.add(jsonObject3);
             }
+            //2.3 将三级分类集合加入到二级分类对象"categoryChild"中
             jsonObject2.put("categoryChild", jsonObject3List);
             jsonObject2List.add(jsonObject2);
         }
-        //2.4 将2级分类集合存入1级分类categoryChild
+        //2.3 将三级分类集合加入到二级分类对象"categoryChild"
         jsonObject1.put("categoryChild", jsonObject2List);
         return jsonObject1;
     }
@@ -2207,20 +2230,20 @@ POST album_info/_search
 
 ```java
 /**
- * 根据1级分类ID查询置顶3级分类列表
+ * 根据一级分类Id查询置顶7个三级分类列表
  * @param category1Id
  * @return
  */
 @GetMapping("/category/findTopBaseCategory3/{category1Id}")
-public Result<List<BaseCategory3>> getTopBaseCategory3(@PathVariable Long category1Id);
+public Result<List<BaseCategory3>> findTopBaseCategory3(@PathVariable Long category1Id);
 ```
 
 **AlbumDegradeFeignClient服务降级类**
 
 ```java
 @Override
-public Result<List<BaseCategory3>> getTopBaseCategory3(Long category1Id) {
-    log.error("[专辑服务]远程调用getTopBaseCategory3执行服务降级");
+public Result<List<BaseCategory3>> findTopBaseCategory3(Long category1Id) {
+    log.error("[专辑服务]远程调用findTopBaseCategory3执行服务降级");
     return null;
 }
 ```
@@ -2231,14 +2254,14 @@ public Result<List<BaseCategory3>> getTopBaseCategory3(Long category1Id) {
 
 ```java
 /**
- * 查询置顶3级分类热度TOP6专辑列表
+ * 查询1级分类下置顶3级分类热度TOP6专辑
  * @param category1Id
- * @return
+ * @return [{"baseCategory3":{三级分类对象},list:[专辑列表]},,{其他6个置顶分类热门专辑Map}]
  */
-@Operation(summary = "查询置顶3级分类热度TOP6专辑列表")
+@Operation(summary = "查询1级分类下置顶3级分类热度TOP6专辑")
 @GetMapping("/albumInfo/channel/{category1Id}")
-public Result<List<Map<String, Object>>> searchTopCategoryHotAlbum(@PathVariable Long category1Id){
-    List<Map<String, Object>> list = searchService.searchTopCategoryHotAlbum(category1Id);
+public Result<List<Map<String, Object>>> channel(@PathVariable Long category1Id) {
+    List<Map<String, Object>> list = searchService.channel(category1Id);
     return Result.ok(list);
 }
 ```
@@ -2247,89 +2270,95 @@ public Result<List<Map<String, Object>>> searchTopCategoryHotAlbum(@PathVariable
 
 ```java
 /**
- * 查询置顶3级分类热度TOP6专辑列表
+ * 查询1级分类下置顶3级分类热度TOP6专辑
  * @param category1Id
- * @return
+ * @return [{"baseCategory3":{三级分类对象},list:[专辑列表]},,{其他6个置顶分类热门专辑Map}]
  */
-List<Map<String, Object>> searchTopCategoryHotAlbum(Long category1Id);
+List<Map<String, Object>> channel(Long category1Id);
 ```
 
 **SearchServiceImpl**实现类:
 
 ```java
 /**
- * 查询置顶3级分类热度TOP6专辑列表
+ * 查询1级分类下置顶3级分类热度TOP6专辑
  *
  * @param category1Id
- * @return
+ * @return [{"baseCategory3":{三级分类对象},list:[专辑列表]},,{其他6个置顶分类热门专辑Map}]
  */
 @Override
-public List<Map<String, Object>> searchTopCategoryHotAlbum(Long category1Id) {
+public List<Map<String, Object>> channel(Long category1Id) {
     try {
-        //1.根据1级分类ID远程调用专辑服务获取6个置顶三级分类 用于检索ES条件,及封装Map中分类对象
-        List<BaseCategory3> category3List = albumFeignClient.getTopBaseCategory3(category1Id).getData();
-        Assert.notNull(category3List, "未查询到{}置顶分类", category1Id);
-        //1.1 检索多关键字精确查询查询条件FiledValue类型 将集合泛型从BaseCategory3转为FiledValue(封装3级分类ID)
-        List<FieldValue> fieldValueList = category3List
+        //1.根据1级分类ID获取置顶三级分类ID
+        //1.1 远程调用远程调用专辑微服务获取置顶3级分类
+        List<BaseCategory3> baseCategory3List = albumFeignClient.findTopBaseCategory3(category1Id).getData();
+        Assert.notNull(baseCategory3List, "一级分类{}置顶三级分类不存在", category1Id);
+
+        //1.2 获取置顶三级分类ID列表
+        List<FieldValue> fieldValueList = baseCategory3List
                 .stream()
-                .map(category3 -> FieldValue.of(category3.getId()))
+                .map(c3 -> FieldValue.of(c3.getId()))
                 .collect(Collectors.toList());
 
-        //1.2 将三级分类List转为Map<Long, BaseCategory3> Map中key:三级分类ID Value:三级分类对象
-        Map<Long, BaseCategory3> category3Map = category3List
+        //1.3 为了封装结果Map中分类对象,将三级分类List转为Map<3级分类ID,3级分类对象>
+        Map<Long, BaseCategory3> category3Map = baseCategory3List
                 .stream()
-                .collect(Collectors.toMap(BaseCategory3::getId, c3 -> c3));
+                .collect(Collectors.toMap(BaseCategory3::getId, baseCategory3 -> baseCategory3));
 
-
-        //2.根据查询条件:7个三级分类ID 聚合:根据三级分类ID聚合(子聚合:按照热度进行排序)检索ES
+        //2. 调用ES进行检索:置顶分类热门专辑
         SearchResponse<AlbumInfoIndex> searchResponse = elasticsearchClient.search(
-                s -> s.index(INDE_NAME)
+                s -> s.index(INDEX_NAME)
+                        .size(0)
                         .query(q -> q.terms(t -> t.field("category3Id").terms(t1 -> t1.value(fieldValueList))))
-                        .aggregations("category3_agg",
-                                a -> a.terms(t -> t.field("category3Id").size(10))
-                                        .aggregations("top6", a1 -> a1.topHits(t -> t.size(6).sort(
-                                                sort -> sort.field(f -> f.field("hotScore").order(SortOrder.Desc))
-                                        )))
+                        .aggregations(
+                                "c3_agg", a -> a.terms(t -> t.field("category3Id").size(7))
+                                        .aggregations("top6", a1 -> a1.topHits(
+                                                t -> t.size(6)
+                                                        .sort(s1 -> s1.field(f -> f.field("hotScore").order(SortOrder.Desc)))
+                                                        .source(s1 -> s1.filter(f -> f.excludes("attributeValueIndexList",
+                                                                "hotScore",
+                                                                "commentStatNum",
+                                                                "buyStatNum",
+                                                                "subscribeStatNum",
+                                                                "announcerName")))
+                                        ))
                         )
-                        .size(0),
-                AlbumInfoIndex.class);
-
-        //2.解析ES检索结果封装置顶分类热门专辑Map对象
-        //2.1 根据分类ID聚合名称从ES检索响应对象获取聚合结果
-        LongTermsAggregate category3Agg = searchResponse.aggregations().get("category3_agg").lterms();
-        //2.2 遍历三级分类桶(Bucket)数组,每遍历一个Bucket封装置顶分类热门专辑Map对象
-        List<LongTermsBucket> bucketList = category3Agg.buckets().array();
-        if (CollectionUtil.isNotEmpty(bucketList)) {
-            List<Map<String, Object>> list = bucketList
+                , AlbumInfoIndex.class);
+
+        //3.解析聚合结果,获取置顶分类包含热度TOP6专辑列表 将7个置顶分类热门专辑Map封装到List集合中
+        List<LongTermsBucket> longTermsBuckets = searchResponse.aggregations().get("c3_agg").lterms().buckets().array();
+        //3.1 遍历三级分类聚合结果,每遍历一次就封装一个置顶分类热门专辑Map对象
+        if (CollUtil.isNotEmpty(longTermsBuckets)) {
+            List<Map<String, Object>> topCategory3MapList = longTermsBuckets
                     .stream()
-                    .map(c3Bucket -> {
-                        //2.2.1 获取外层聚合结果中key(三级分类ID)
-                        long category3Id = c3Bucket.key();
-                        //2.2.2 获取当前聚合内包含子聚合(按照组内专辑热度排序)
-                        TopHitsAggregate top6Aggregate = c3Bucket.aggregations().get("top6").topHits();
-                        //2.2.3 遍历子聚合Bucket得到热度TOP6专辑列表
-                        List<Hit<JsonData>> hitsList = top6Aggregate.hits().hits();
-                        if (CollectionUtil.isNotEmpty(hitsList)) {
-                            List<AlbumInfoIndex> top6List = hitsList.stream().map(hit -> {
-                                //获取热门专辑JSON字符串
-                                String sourceStr = hit.source().toString();
-                                //将JSON转为专辑文档对象
-                                AlbumInfoIndex albumInfoIndex = JSON.parseObject(sourceStr, AlbumInfoIndex.class);
-                                return albumInfoIndex;
-                            }).collect(Collectors.toList());
-                            //2.3 封装当前置顶分类热门专辑Map对象
-                            Map<String, Object> map = new HashMap<>();
-                            map.put("baseCategory3", category3Map.get(category3Id));
-                            map.put("list", top6List);
-                            return map;
+                    .map(bucket -> {
+                        //3.1.1 创建Map封装置顶分类热门专辑
+                        Map<String, Object> map = new HashMap<>();
+                        //3.1.2 获取聚合结果中三级分类ID
+                        long topCategory3Id = bucket.key();
+                        //3.1.3 获取top6专辑列表
+                        //获取三级分类聚合内子聚合"top6"
+                        List<Hit<JsonData>> top6HitsList = bucket.aggregations().get("top6")
+                                .topHits().hits().hits();
+                        if (CollUtil.isNotEmpty(top6HitsList)) {
+                            //遍历Hit集合 将集合泛型从Hit转为AlbumInfoIndex类型
+                            List<AlbumInfoIndex> topAlbumList = top6HitsList.stream()
+                                    .map(hit -> {
+                                        //获取专辑JSON字符串
+                                        String albumInfoIndexJSONStr = hit.source().toString();
+                                        //将专辑JSON字符串转为AlbumInfoIndex对象
+                                        AlbumInfoIndex albumInfoIndex = JSON.parseObject(albumInfoIndexJSONStr, AlbumInfoIndex.class);
+                                        return albumInfoIndex;
+                                    }).collect(Collectors.toList());
+                            //3.2 封装置顶分类热门专辑Map
+                            map.put("baseCategory3", category3Map.get(topCategory3Id));
+                            map.put("list", topAlbumList);
                         }
-                        return null;
+                        return map;
                     }).collect(Collectors.toList());
-            //3.返回检索结果集合对象
-            return list;
+            return topCategory3MapList;
         }
     } catch (IOException e) {
-        log.error("[检索服务]检索置顶分类热门专辑异常:{}", e);
         throw new RuntimeException(e);
     }
     return null;