码迷,mamicode.com
首页 > 其他好文 > 详细

学成在线(第11天)

时间:2020-02-06 14:47:40      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:http   ace   多个   清除   ext   cas   启动   exp   sig   

 课程搜索需求分析

 需求分析

技术图片

1、根据分类搜索课程信息。
2、根据关键字搜索课程信息,搜索方式为全文检索,关键字需要匹配课程的名称、 课程内容。
3、根据难度等级搜索课程。
4、搜索结点分页显示。

 搜索流程

技术图片

1、课程管理服务将数据写到MySQL数据库
2、使用Logstash将MySQL数据库中的数据写到ES的索引库。
3、用户在前端搜索课程信息,请求到搜索服务。
4、搜索服务请求ES搜索课程信息。

课程索引

如何维护课程索引信息?
1、当课程向MySQL添加后同时将课程信息添加到索引库。
采用Logstach实现,Logstach会从MySQL中将数据采集到ES索引库。
2、当课程在MySQL更新信息后同时更新该课程在索引库的信息。
采用Logstach实现。
3、当课程在MySQL删除后同时将该课程从索引库删除。
手工写程序实现,在删除课程后将索引库中该课程信息删除。

准备课程索引信息

课程发布成功在MySQL数据库存储课程发布信息,此信息作为课程索引信息。

创建课程发布表

课程信息分布在course_base、course_pic等不同的表中。
课程发布成功为了方便进行索引将这几张表的数据合并在一张表中,作为课程发布信息。
创建course_pub表

创建课程发布表模型

在课程管理服务创建模型:

技术图片
@Data
@ToString
@Entity
@Table(name="course_pub")
@GenericGenerator(name = "jpa‐assigned", strategy = "assigned")
public class CoursePub implements Serializable {
    private static final long serialVersionUID = ‐916357110051689487L;
    @Id
    @GeneratedValue(generator = "jpa‐assigned")
    @Column(length = 32)
    private String id;
private String name;
    private String users;
    private String mt;
    private String st;
    private String grade;
    private String studymodel;
    private String teachmode;
    private String description;
    private String pic;//图片
    private Date timestamp;//时间戳
    private String charge;
    private String valid;
    private String qq;
    private Float price;
    private Float price_old;
    private String expires;
    private String teachplan;//课程计划
    @Column(name="pub_time")
    private String pubTime;//课程发布时间
}
View Code

 修改课程发布

在课程管理服务定义dao:
1)创建course_pub表的dao

public interface CoursePubRepository extends JpaRepository<CoursePub, String> {
}

2) 修改课程发布service

技术图片
 //保存CoursePub
    public CoursePub saveCoursePub(String id, CoursePub coursePub){
        if(StringUtils.isNotEmpty(id)){
            ExceptionCast.cast(CourseCode.COURSE_PUBLISH_COURSEIDISNULL);
        }
        CoursePub coursePubNew null;
        Optional<CoursePub> coursePubOptional = coursePubRepository.findById(id);
        if(coursePubOptional.isPresent()){
            coursePubNew = coursePubOptional.get();
        }
        if(coursePubNew == null){
            coursePubNew new CoursePub();
        }
        BeanUtils.copyProperties(coursePub,coursePubNew);
        //设置主键
        coursePubNew.setId(id);
        //更新时间戳为最新时间
        coursePub.setTimestamp(new Date());
        //发布时间
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY‐MM‐dd HH:mm:ss");
        String date = simpleDateFormat.format(new Date());
        coursePub.setPubTime(date);
        coursePubRepository.save(coursePub);
        return coursePub;
    }
    //创建coursePub对象
    private CoursePub createCoursePub(String id){
        CoursePub coursePub new CoursePub();
        coursePub.setId(id);
        //基础信息
        Optional<CourseBase> courseBaseOptional = courseBaseRepository.findById(id);
        if(courseBaseOptional == null){
            CourseBase courseBase = courseBaseOptional.get();
            BeanUtils.copyProperties(courseBase, coursePub);
        }
        //查询课程图片
        Optional<CoursePic> picOptional = coursePicRepository.findById(id);
        if(picOptional.isPresent()){
            CoursePic coursePic = picOptional.get();
            BeanUtils.copyProperties(coursePic, coursePub);
        }
        //课程营销信息
        Optional<CourseMarket> marketOptional = courseMarketRepository.findById(id);
        if(marketOptional.isPresent()){
            CourseMarket courseMarket = marketOptional.get();
            BeanUtils.copyProperties(courseMarket, coursePub);
        }
        //课程计划
        TeachplanNode teachplanNode = teachplanMapper.selectList(id);
        //将课程计划转成json
        String teachplanString = JSON.toJSONString(teachplanNode);
        coursePub.setTeachplan(teachplanString);
        return coursePub;
    }
View Code

修改课程发布方法,添加调用saveCoursePub方法的代码,添加部分的代码如下:

//课程发布
    @Transactional
    public CoursePublishResult publish(String courseId){
        ....
        //创建课程索引
        //创建课程索引信息
        CoursePub coursePub = createCoursePub(courseId);
        //向数据库保存课程索引信息
        CoursePub newCoursePub = saveCoursePub(courseId, coursePub);
 if(newCoursePub==null){
            //创建课程索引信息失败
            ExceptionCast.cast(CourseCode.COURSE_PUBLISH_CREATE_INDEX_ERROR);
        }
       ....
    }

 搭建ES环境

开发环境使用ES单机环境,启动ES服务端。
注意:旧的ES环境,可以删除elasticsearch-6.2.1\data\nodes目录以完全清除ES环境。
安装elasticsearch-head并启动。

创建索引库

创建索引库
创建xc_course索引库,一个分片,0个副本。

创建映射

在postman里添加映射

Post http://localhost:9200/xc_course/doc/_mapping

{
"properties" : {

            "description" : {
                "analyzer" : "ik_max_word", 
            "search_analyzer": "ik_smart",
                "type" : "text"
            },
            "grade" : {
                "type" : "keyword"
            },
            "id" : {
                "type" : "keyword"
            },
            "mt" : {
                "type" : "keyword"
            },
            "name" : {
                "analyzer" : "ik_max_word", 
            "search_analyzer": "ik_smart",
                "type" : "text"
            },
            "users" : {
                "index" : false, 
                "type" : "text"
            },
            "charge" : {
                "type" : "keyword"
            },
            "valid" : {
                "type" : "keyword"
            },
            "pic" : {
                "index" : false, 
                "type" : "keyword"
            },
            "qq" : {
                "index" : false, 
                "type" : "keyword"
            },
            "price" : {
                "type" : "float"
            },
            "price_old" : {
                "type" : "float"
            },
            "st" : {
                "type" : "keyword"
            },
            "status" : {
                "type" : "keyword"
            },
            "studymodel" : { 
                "type" : "keyword"
            },
            "teachmode" : {
                "type" : "keyword"
            },
            "teachplan" : {
                "analyzer" : "ik_max_word", 
            "search_analyzer": "ik_smart",
                "type" : "text"
            },

            "expires" : {
                "type" : "date", 
            "format": "yyyy-MM-dd HH:mm:ss"
            },
            "pub_time" : {
                "type" : "date", 
            "format": "yyyy-MM-dd HH:mm:ss"
            },
            "start_time" : {
                "type" : "date", 
            "format": "yyyy-MM-dd HH:mm:ss"
            },
            "end_time" : {
                "type" : "date", 
            "format": "yyyy-MM-dd HH:mm:ss"
            }
        }
    }

技术图片

 Logstash 创建索引

Logstash是ES下的一款开源软件,它能够同时 从多个来源采集数据、转换数据,然后将数据发送到Eleasticsearch
中创建索引。
本项目使用Logstash将MySQL中的数据采用到ES索引中。

这里资料给的配套文件有很多坑,我把坑都踩了一遍,下面分享解决方法。

下载Logstash

下载Logstash6.2.1版本,和本项目使用的Elasticsearch6.2.1版本一致,版本要一致

安装logstash-input-jdbc

这里解压老师提供的logstash-6.2.1.zip即可,此logstash中已集成了logstash-input-jdbc插件

创建模板文件

Logstash的工作是从MySQL中读取数据,向ES中创建索引,这里需要提前创建mapping的模板文件以便logstash
使用。
在logstach的config目录创建xc_course_template.json,内容如下:

{
   "mappings" : {
      "doc" : {
         "properties" : {
            "charge" : {
               "type" : "keyword"
            },
            "description" : {
               "analyzer" : "ik_max_word",
               "search_analyzer" : "ik_smart",
               "type" : "text"
            },
            "end_time" : {
               "format" : "yyyy-MM-dd HH:mm:ss",
               "type" : "date"
            },
            "expires" : {
               "format" : "yyyy-MM-dd HH:mm:ss",
               "type" : "date"
            },
            "grade" : {
               "type" : "keyword"
            },
            "id" : {
               "type" : "keyword"
            },
            "mt" : {
               "type" : "keyword"
            },
            "name" : {
               "analyzer" : "ik_max_word",
               "search_analyzer" : "ik_smart",
               "type" : "text"
            },
            "pic" : {
               "index" : false,
               "type" : "keyword"
            },
            "price" : {
               "type" : "float"
            },
            "price_old" : {
               "type" : "float"
            },
            "pub_time" : {
               "format" : "yyyy-MM-dd HH:mm:ss",
               "type" : "date"
            },
            "qq" : {
               "index" : false,
               "type" : "keyword"
            },
            "st" : {
               "type" : "keyword"
            },
            "start_time" : {
               "format" : "yyyy-MM-dd HH:mm:ss",
               "type" : "date"
            },
            "status" : {
               "type" : "keyword"
            },
            "studymodel" : {
               "type" : "keyword"
            },
            "teachmode" : {
               "type" : "keyword"
            },
            "teachplan" : {
               "analyzer" : "ik_max_word",
               "search_analyzer" : "ik_smart",
               "type" : "text"
            },
            "users" : {
               "index" : false,
               "type" : "text"
            },
            "valid" : {
               "type" : "keyword"
            }
         }
      }
   },
   "template" : "xc_course"
}

配置mysql.conf

在logstash的config目录下配置mysql.conf文件供logstash使用,logstash会根据mysql.conf文件的配置的地址从
MySQL中读取数据向ES中写入索引。

配置输入数据源和输出数据源。

input {
  stdin {
  }
  jdbc {
  jdbc_connection_string => "jdbc:mysql://localhost:3306/xc_course?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC"
  # the user we wish to excute our statement as
  jdbc_user => "root"
  #密码记得加双引号
  jdbc_password => ""
  # the path to our downloaded jdbc driver
  #配置本地仓库的mysql数据源jar的路径  
  jdbc_driver_library => "D:/Maven/m2/repository/mysql/mysql-connector-java/5.1.40/mysql-connector-java-5.1.40.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 => "/conf/course.sql"
  statement => "select * from course_pub where timestamp > date_add(:sql_last_value,INTERVAL 8 HOUR)"
  #定时配置
  schedule => "* * * * *"
  record_last_run => true
  #配置本地logstash_metadata存放路径,上一次检索数据的时间点
  last_run_metadata_path => "D:/ElasticSearch01/logstash-6.2.1/config/logstash_metadata"
  }
}


output {
  elasticsearch {
  #ES的ip地址和端口
  hosts => "localhost:9200"
  #hosts => ["localhost:9200","localhost:9202","localhost:9203"]
  #ES索引库名称
  index => "xc_course"
  document_id => "%{id}"
  document_type => "doc"
  #覆盖本地的conf的json数据,同上
  template =>"D:/ElasticSearch01/logstash-6.2.1/config/xc_course_template.json"
  template_name =>"xc_course"
  template_overwrite =>"true"
  }
  stdout {
 #日志输出
  codec => json_lines
  }
}

说明:
1、ES采用UTC时区问题
ES采用UTC 时区,比北京时间早8小时,所以ES读取数据时让最后更新时间加8小时
where timestamp > date_add(:sql_last_value,INTERVAL 8 HOUR)
2、logstash每个执行完成会在D:/ElasticSearch01/logstash-6.2.1/config/logstash_metadata记录执行时间下次以此
时间为基准进行增量同步数据到索引库。

测试

logstash.bat ‐f ..\config\mysql.conf

技术图片

启动测试前,要把D:\ElasticSearch01\logstash-6.2.1\bin下的logstash.bat的最后一行的classpath加双冒号,不然启动不了,报找不到启动类。

技术图片

 

 技术图片

 改好后重新启动

技术图片

 

 只查到一个数据,这里也有坑。要把logstash_metadata里的上一次记录的时间改比数据库所有的时间都要小!!

statement => "select * from course_pub where timestamp > date_add(:sql_last_value,INTERVAL 8 HOUR)"

技术图片

 

技术图片

 改了后,可以看到可以查到所有数据了!

技术图片

 再去查看Elasticsearch,但是数据获取不到,显示不出来??数据已经在更新了啊!

技术图片

 有延时?无论我怎么重启,重装都是这样。。。

技术图片

 最后各种翻博客,卸载重装,查看Elasticsearch的日志文件,不断摸索才发现问题所在。

技术图片

 

 这里说的是xc_course_template.json的pub_time中的日期格式和postman里添加映射的日期格式两次不一致导致的!

这是PDF复制过去的锅,原先日期格式的"-"为中文格式,要改成英文格式!!

照着上面步骤再重新弄一遍,把坑避免,可以看到终于成功了!!!

技术图片

 

 最后总结一下出现的bug:

1.mysql.conf配置文件中的数据库密码加双引号

2.bin下的logstash.bat的最后一行的classpath加双冒号

3.要把logstash_metadata里的上一次记录的时间改比数据库所有的时间都要小

4.xc_course_template.json的pub_time中的日期格式和postman里添加映射的日期格式中的"-"为中文格式,要改成英文格式

遇到bug的时候不要急躁,要有耐心,一次不行就卸载重装再试。可以先做其他事分散注意力,一定找问题出在哪里,通过他人的博客寻求思路。

不断摸索,一定可以迎刃而解,可以提升自己解决bug的能力。

 

 

 

 

学成在线(第11天)

标签:http   ace   多个   清除   ext   cas   启动   exp   sig   

原文地址:https://www.cnblogs.com/anan-java/p/12268307.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!