栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

课程检索功能开发

课程检索功能开发

对于课程搜索页面中,需要完成下面的功能,如下:

课程搜索功能
课程搜索功能需求:
1,分页数据查询
2,根据关键字进行查询
3,根据课程分类和课程等级条件查询
根据关键字进行查询后的内容要高亮显示
在上面的查询条件需求中,需要使用DSL不同的查询方式进行实现。
1,关键字查询,要查询name和description中的数据,对此要使用MatchQuery查询方式来进行查询,查询的数据会先分词再查询。
2,课程等级和课程分类查询,要使用精确匹配,对此使用termQuery查询方式来查询,查询数据不会进行分词
3,优于是多个查询方式共同进行查询,对此要使用BooleanQuery来组合多个查询方式
4,对于课程等级和课程分类精确匹配查询,课程使用BooleanQuery查询中的过滤器来查询数据,这样可以提高查询效率
课程检索交互流程如下:

步骤描述:
1,前端输入检索参数,发起课程检索请求
2,课程搜索服务封装检索参数为ES检索条件,向ES服务发起检索请求
3,ES服务执行检索,并返回检索结果
4,课程检索服务封装ES检索结果为课程信息列表,最终返回给前端

1.2 课程检索接口定义

1.接口参数列表

根据前后端传入参数列表来定义接口

接口传入传出列表



2.传入传出参数封装类

传入参数封装

在 xc-api 工程的 com.xuecheng.api.search.model.qo 包下创建类,如下:

QueryCoursePubModel为课程检索参数

@ApiModel(value = "QueryCoursePubModel",description = "课程索引搜索条件查询对象")
public class QueryCoursePubModel {

    @ApiModelProperty("查询关键字")
    private String keyword;

    @ApiModelProperty("课程二级分类")
    private String mt;

    @ApiModelProperty("课程三级分类")
    private String st;

    @ApiModelProperty("课程等级")
    private String grade;

    @ApiModelProperty("排序字段, 推荐/最新/热评")
    private String sortFiled;
}

传出参数封装类

在 xc-api 工程的 com.xuecheng.api.search.model 包下创建类,如下:

CoursePubIndexDTO为检索返回的课程信息

@Data
@ApiModel(value="CoursePubIndexDTO", description="课程发布")
public class CoursePubIndexDTO implements Serializable {

    @ApiModelProperty(value = "主键")
    private Long indexId;

    @ApiModelProperty(hidden = true)
    private Long course_id;

    @ApiModelProperty(value = "课程标识",example = "1")
    public Long getCourseId() {
        return course_id;
    }

    @ApiModelProperty(hidden = true)
    private Long company_id;

    @ApiModelProperty(value = "机构ID",example = "1")
    public Long getCompanyId() {
        return company_id;
    }

    @ApiModelProperty(hidden = true)
    private String company_name;

    @ApiModelProperty(value = "公司名称")
    public String getCompanyName() {
        return company_name;
    }

    @ApiModelProperty(value = "课程名称")
    private String name;

    @ApiModelProperty(value = "适用人群")
    private String users;

    @ApiModelProperty(value = "标签")
    private String tags;

    @ApiModelProperty(value = "大分类")
    private String mt;

    @ApiModelProperty(value = "大分类名称")
    private String mtName;

    @ApiModelProperty(value = "小分类")
    private String st;

    @ApiModelProperty(value = "小分类名称")
    private String stName;

    @ApiModelProperty(value = "课程等级")
    private String grade;

    @ApiModelProperty(value = "教育模式(common普通,record 录播,live直播等)")
    private String teachmode;

    @ApiModelProperty(value = "课程图片")
    private String pic;

    @ApiModelProperty(value = "课程介绍")
    private String description;

    @ApiModelProperty(value = "所有课程计划,json格式")
    private String teachplan;

    @ApiModelProperty(hidden = true)
    private Date create_date;

    @ApiModelProperty(value = "发布时间")
    public Date getCreateDate() {
        return create_date;
    }

    @ApiModelProperty(hidden = true)
    private Date change_date;

    @ApiModelProperty(value = "修改时间")
    public Date getChangeDate() {
        return change_date;
    }

    @ApiModelProperty(hidden = true)
    private Integer is_latest;

    @ApiModelProperty(value = "是否最新课程(1最新)")
    public Integer getIsLatest() {
        return is_latest;
    }

    @ApiModelProperty(hidden = true)
    private Integer is_pub;

    @ApiModelProperty(value = "是否发布(1发布 0取消发布)")
    public Integer getIsPub() {
        return is_pub;
    }

    @ApiModelProperty(value = "状态(1正常  0删除)")
    private String status;

    @ApiModelProperty(value = "备注")
    private String remark;
    
    @ApiModelProperty(value = "课程营销数据")
    private String market;
    
    @ApiModelProperty(value = "收费规则,对应数据字典--203")
    private String charge;

    @ApiModelProperty(value = "现价")
    private Float price;

    @ApiModelProperty(value = "有效性,对应数据字典--204")
    private String valid;

    @ApiModelProperty(value = "学习人数")
    private Long learners;
    
    @ApiModelProperty(value = "课程评论数")
    private Long comment_num;
}
1.3 接口实现

(1)服务层实现

接口定义:

在 xc-content-search-service 工程的 **com.xuecheng.search.service**包下新增以下接口:

public interface CoursePubSearchService {

    
    PageVO queryCoursePubIndex(PageRequestParams pageRequestParams, QueryCoursePubModel queryModel);
}

服务层实现:

在 xc-content-search-service 工程的 **com.xuecheng.search.service.impl**包下新增以下实现类:

package com.xuecheng.search.service.impl;

import com.xuecheng.api.search.model.dto.CoursePubIndexDTO;
import com.xuecheng.api.search.model.qo.QueryCoursePubIndexModel;
import com.xuecheng.common.domain.page.PageRequestParams;
import com.xuecheng.common.domain.page.PageVO;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.common.util.JsonUtil;
import com.xuecheng.common.util.StringUtil;
import com.xuecheng.search.common.constant.ContentSearchErrorCode;
import com.xuecheng.search.service.CoursePubSearchService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;


@Slf4j
@Service
public class CoursePubSearchServiceImpl implements CoursePubSearchService {
  @Value("${xuecheng.elasticsearch.course.index}")
    private String indexName;

    @Autowired
    private RestHighLevelClient client;

    
    public PageVO queryCoursePubIndex(PageRequestParams params,
                                                             QueryCoursePubModel model) {
        PageVO pageVO = null;


        try {
            // 1.创建出SearchRequest
            SearchRequest request = getSearchRequest(params,model);

            // 2.获得响应数据SearchResponse
            SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);

            // 3.解析结果数据并封装PageVO中
            pageVO = parseResponse(searchResponse,params);
        } catch (IOException e) {
            log.error("课程搜索数据失败:{}", e.getMessage());
            ExceptionCast.cast(ContentSearchErrorCode.E_150001);
        }

        return pageVO;
    }

    
    private PageVO parseResponse(SearchResponse searchResponse,PageRequestParams params) {

        // 1.获得响应数据的大hits
        SearchHits hits = searchResponse.getHits();

        // 2.查询的总条数
        long totalCount = hits.getTotalHits().value;

        // 3.获得小hits
        SearchHit[] hitsHits = hits.getHits();


        ArrayList list = new ArrayList<>();

        // 4.遍历小hits封装数据到PageVO中
        for (SearchHit hitsHit : hitsHits) {

            // 获得文档的源数据内容
            String id = hitsHit.getId();

            String jsonString = hitsHit.getSourceAsString();

            CoursePubIndexDTO dto = JsonUtil.jsonToObject(jsonString, CoursePubIndexDTO.class);

            dto.setIndexId(new Long(id));

            // 获得高亮数据
            Map highlightFields = hitsHit.getHighlightFields();

            HighlightField highlightField = highlightFields.get("name");

            if (!(ObjectUtils.isEmpty(highlightField))) {

                Text[] fragments = highlightField.getFragments();

                StringBuilder stringBuilder = new StringBuilder();

                for (Text fragment : fragments) {
                    stringBuilder.append(fragment);
                }

                String highLightName = stringBuilder.toString();

                dto.setName(highLightName);
            }

            list.add(dto);
        }

        PageVO pageVO = new PageVO<>(list,totalCount,params.getPageNo(),params.getPageSize());

        return pageVO;
    }

    
    private SearchRequest getSearchRequest(PageRequestParams params,
                                           QueryCoursePubModel model) {

        // 0.判断分页数据
        if (params.getPageNo() < 1) {
            params.setPageNo(PageRequestParams.DEFAULT_PAGE_NUM);
        }
        if (params.getPageSize() < 1) {
            params.setPageSize(PageRequestParams.DEFAULT_PAGE_SIZE);
        }


        // 1.创建SearchRequest对象
        SearchRequest request = new SearchRequest(indexName);

        // 2.创建搜索源数据对象
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // 2.1 设置分页数据

        Long pageNo = params.getPageNo();

        Integer pageSize = params.getPageSize();


        int from = (pageNo.intValue() - 1) * pageSize;

        sourceBuilder.from(from);
        sourceBuilder.size(pageSize);



        // 2.2 设置高亮数据
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("");
        highlightBuilder.postTags("");
        highlightBuilder.fields().add(new HighlightBuilder.Field("name"));

        sourceBuilder.highlighter(highlightBuilder);


        // 3.构建查询方式
        
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();



        String keyword = model.getKeyword();
        if (StringUtil.isNotBlank(keyword)) {
            MultiMatchQueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(keyword, "name", "description")
                    .minimumShouldMatch("80%").field("name",3);
            boolQueryBuilder.must(queryBuilder);
        }


        String grade = model.getGrade();
        String mt = model.getMt();
        String st = model.getSt();


        if (StringUtil.isNotBlank(grade)) {
            TermQueryBuilder gradeTerm = QueryBuilders.termQuery("grade", grade);
            boolQueryBuilder.filter(gradeTerm);
        }

        if (StringUtil.isNotBlank(mt)) {
            TermQueryBuilder mtTerm = QueryBuilders.termQuery("mt", mt);
            boolQueryBuilder.filter(mtTerm);
        }

        if (StringUtil.isNotBlank(st)) {
            TermQueryBuilder stTerm = QueryBuilders.termQuery("st", st);
            boolQueryBuilder.filter(stTerm);
        }


        sourceBuilder.query(boolQueryBuilder);


        // 将查询源数据对象存放到Request
        request.source(sourceBuilder);


        return request;
    }
}

(2)Controller实现

CoursePubSearchController中实现课程检索接口

@RestController
@RequestMapping
public class CoursePubSearchController implements CoursePubSearchApi {

    @Resource 
    private CoursePubSearchService couresPubSearchService;


    @PostMapping("course_index")
    public PageVO coursePubIndexByCondition(PageRequestParams pageParams, @RequestBody QueryCoursePubModel queryModel) {
        PageVO pageVO = couresPubSearchService.queryCoursePubIndex(pageParams, queryModel);
        return pageVO;
    }

}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/742524.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号