谷粒学院项目完善 增加搜索模块 门户个人中心

谷粒学院项目 完善增加搜索模块 门户个人中心

后端代码:https://gitee.com/wodful/edu_admin.git
前端代码:
门户:https://gitee.com/wodful/edu_front.git
后台管理:https://gitee.com/wodful/edu_parent.git
项目视频教程

B站 谷粒学院-2020版微服务-全栈在线教育实战项目地址:https://b23.tv/hteMbT
后端技术
需要的工具: ElasticSearch-1 和logstash-6.21
链接:https://pan.baidu.com/s/1y4frSse1FXv-El83IfxQuQ
提取码:0gcs
复制这段内容后打开百度网盘手机App,操作更方便哦
使用postMan创建索引和映射:
put: http://localhost:9200/edu_course
put:http://localhost:9200/edu_course/CourseSearchEntity/_mapping

{
	 "properties": {
        "title": {
          "type": "text",
          "analyzer": "ik_max_word"
        },
        "teacher_name": {
          "type": "text",
          "analyzer": "ik_max_word"
        },
        "course_description": {
          "type": "text",
          "analyzer": "ik_max_word"
        },
        "price": {
          "type": "float"
        },
        "cover": {
          "type": "keyword"
        },
        "view_count": {
          "type": "long"
        },
        "buy_count": {
          "type": "long"
        },
		"subject_parent_id" : {
            "type" : "keyword"
        },
		"subject_id" : {
            "type" : "keyword"
        },
		"gmt_create" : {
            "type" : "date"
        },
		"teacher_id" : {
            "index" : false,
            "type" : "text"
        }
  }
}

``搜索关键代码块

public Result list(Long page, Long limit, CourseSearchParam
            courseSearchParam){
        //设置索引
        SearchRequest searchRequest = new SearchRequest(es_index);
        //设置类型
        searchRequest.types(es_type);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //source源字段过虑
        String[] source_fields = source_field.split(",");
        searchSourceBuilder.fetchSource(source_fields, new String[]{});
        //关键字
        if(StringUtils.isNotEmpty(courseSearchParam.getKeyword())){
            //匹配关键字
            MultiMatchQueryBuilder multiMatchQueryBuilder =
                    QueryBuilders.multiMatchQuery(courseSearchParam.getKeyword(), "title",
                            "teacher_name","course_description");
            //设置匹配占比
            multiMatchQueryBuilder.minimumShouldMatch("70%");
            //提升另个字段的Boost值
            multiMatchQueryBuilder.field("title",10);
            boolQueryBuilder.must(multiMatchQueryBuilder);
        }
        //过虑
        if(StringUtils.isNotEmpty(courseSearchParam.getSubjectParentId()))
        {
          boolQueryBuilder.filter(QueryBuilders.termQuery("subject_parent_id",courseSearchParam.getSubjectParentId()));
        }
        if(StringUtils.isNotEmpty(courseSearchParam.getSubjectId()))
        {
            boolQueryBuilder.filter(QueryBuilders.termQuery("subject_id",courseSearchParam.getSubjectId()));
        }
        if (StringUtils.isNotEmpty(courseSearchParam.getBuyCountSort())) {
            searchSourceBuilder.sort(new FieldSortBuilder("buy_count").order(SortOrder.DESC));
        }
        if (StringUtils.isNotEmpty(courseSearchParam.getGmtCreateSort())) {
            searchSourceBuilder.sort(new FieldSortBuilder("gmt_create").order(SortOrder.DESC));
        }
        if (StringUtils.isNotEmpty(courseSearchParam.getPriceSort())) {
            searchSourceBuilder.sort(new FieldSortBuilder("price").order(SortOrder.DESC));
        }
        //布尔查询
        searchSourceBuilder.query(boolQueryBuilder);
        //请求搜索
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try {
            searchResponse = restHighLevelClient.search(searchRequest);
//            searchResponse = restClient.sea(searchRequest);

        } catch (IOException e) {
            e.printStackTrace();
//            LOGGER.error("xuecheng search error..{}",e.getMessage());
            return  Result.error().message("搜索相应失败");
        }
        //结果集处理
        SearchHits hits = searchResponse.getHits();
        SearchHit[] searchHits = hits.getHits();
        //记录总数
        long totalHits = hits.getTotalHits();

        List<EduCourseReponse> list =  new ArrayList<>();
        for (SearchHit hit : searchHits) {
            if(MapUtils.isNotEmpty(hit.getSourceAsMap())){
                EduCourseReponse coursePub = new EduCourseReponse();
                //取出source
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                //取出名称
                String title = (String) sourceAsMap.get("title");
                coursePub.setTitle(title);
                //图片
                String cover = (String) sourceAsMap.get("cover");
                coursePub.setCover(cover);
                //价格
                BigDecimal price = null;
                try {
                    if(sourceAsMap.get("price")!=null ){
                        price = new BigDecimal(Double.valueOf((Double) sourceAsMap.get("price")).toString());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                coursePub.setPrice(price);
                Long buyCount = Long.valueOf(sourceAsMap.get("buy_count").toString());
                Long viewCount = Long.valueOf(sourceAsMap.get("view_count").toString());

                coursePub.setBuyCount(buyCount);
                coursePub.setViewCount(viewCount);
                coursePub.setId(sourceAsMap.get("id").toString());
                list.add(coursePub);
            }
        }

        Page<EduCourseReponse> pageParam = new Page<>();
        pageParam.setTotal(totalHits);
        pageParam.setRecords(list);
        pageParam.setCurrent(page);
        pageParam.setSize(limit);
        long current = pageParam.getCurrent();
        long pages = pageParam.getPages();
        long size = pageParam.getSize();
        long total = pageParam.getTotal();
        boolean hasNext = pageParam.hasNext();
        boolean hasPrevious = pageParam.hasPrevious();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("items", list);
        map.put("current", current);
        map.put("pages", pages);
        map.put("size", size);
        map.put("total", total);
        map.put("hasNext", hasNext);
        map.put("hasPrevious", hasPrevious);

        return Result.ok().data(map);
    }```

使用logstash-6.2.1采集数据
edu_course.sql

SELECT
	ec.id,
	ec.title,
	ec.price,
	ec.cover,
	ec.buy_count,
	ec.view_count,
	ecd.description as course_description,
	et.`name` as teacher_name,
	ec.subject_parent_id,
	ec.subject_id,
	ec.gmt_create,
	ec.teacher_id
FROM
	edu_course ec,
	edu_course_description ecd,
	edu_teacher et
WHERE
	ec.id = ecd.id
AND ec.teacher_id = et.id and ec.gmt_modified > date_add(:sql_last_value,INTERVAL 8 HOUR)

模板:edu_course.json

{
  "mappings":{
    "CourseSearchEntity": {
      "properties": {
        "title": {
          "type": "text",
          "analyzer": "ik_max_word"
        },
        "teacher_name": {
          "type": "text",
          "analyzer": "ik_max_word"
        },
        "course_description": {
          "type": "text",
          "analyzer": "ik_max_word"
        },
        "price": {
          "type": "float"
        },
        "cover": {
          "type": "keyword"
        },
        "view_count": {
          "type": "long"
        },
        "buy_count": {
          "type": "long"
        },
		"subject_parent_id" : {
            "type" : "keyword"
        },
		"subject_id" : {
            "type" : "keyword"
        },
		"gmt_create" : {
            "type" : "date"
        },
		"teacher_id" : {
            "index" : false,
            "type" : "text"
        },
      }
    }
  },
   "settings" : {
      "number_of_shards": 1
	  "number_of_replicas": 0
   },
  "template" : "edu_course"
}

mysql.conf 启动logstash 加载此配置文件

input {
  stdin {
  }
  jdbc {
  jdbc_connection_string => "jdbc:mysql://localhost:3306/edu?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC"
  # the user we wish to excute our statement as
  jdbc_user => "root"
  jdbc_password => "123456"
  # the path to our downloaded jdbc driver  
  jdbc_driver_library => "E:/mavenjar/repository/mysql/mysql-connector-java/5.1.41/mysql-connector-java-5.1.41.jar"
  # the name of the driver class for mysql
  jdbc_driver_class => "com.mysql.jdbc.Driver"
  jdbc_paging_enabled => "true"
  jdbc_page_size => "50000"
  #要执行的sql文件
  statement_filepath => "G:/ElasticSearch/logstash-6.2.1/config/edu_course.sql"
  #statement => "select * from course_pub where timestamp > date_add(:sql_last_value,INTERVAL 8 HOUR)"
  #定时配置
  schedule => "* * * * *"
  record_last_run => true
  last_run_metadata_path => "G:/ElasticSearch/logstash-6.2.1/config/logstash_metadata"
  }
}


output {
  elasticsearch {
  #ES的ip地址和端口
  hosts => "localhost:9200"
  #hosts => ["localhost:9200","localhost:9202","localhost:9203"]
  #ES索引库名称
  index => "edu_course"
  document_id => "%{id}"
  document_type => "CourseSearchEntity"
  template =>"G:/ElasticSearch/logstash-6.2.1/config/edu_course.json"
  template_name =>"edu_course"
  template_overwrite =>"true"
  }
  stdout {
 #日志输出
  codec => json_lines
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值