一、根據分類搜索課程信息。
二、根據關鍵字搜索課程信息,搜索方式爲全文檢索,關鍵字須要匹配課程的名稱、 課程內容。
三、根據難度等級搜索課程。
四、搜索結點分頁顯示。前端
一、課程管理服務將數據寫到MySQL數據庫
二、使用Logstash將MySQL數據庫中的數據寫到ES的索引庫。
三、用戶在前端搜索課程信息,請求到搜索服務。
四、搜索服務請求ES搜索課程信息。java
如何維護課程索引信息?
一、當課程向MySQL添加後同時將課程信息添加到索引庫。
採用Logstach實現,Logstach會從MySQL中將數據採集到ES索引庫。
二、當課程在MySQL更新信息後同時更新該課程在索引庫的信息。
採用Logstach實現。
三、當課程在MySQL刪除後同時將該課程從索引庫刪除。
手工寫程序實現,在刪除課程後將索引庫中該課程信息刪除。node
課程發佈成功在MySQL數據庫存儲課程發佈信息,此信息做爲課程索引信息。mysql
課程信息分佈在course_base、course_pic等不一樣的表中。
課程發佈成功爲了方便進行索引將這幾張表的數據合併在一張表中,做爲課程發佈信息。
建立course_pub表sql
在課程管理服務建立模型:數據庫
@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;//課程發佈時間 }
在課程管理服務定義dao:
1)建立course_pub表的daojson
public interface CoursePubRepository extends JpaRepository<CoursePub, String> { }
2) 修改課程發佈serviceapp
//保存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; }
修改課程發佈方法,添加調用saveCoursePub方法的代碼,添加部分的代碼以下:elasticsearch
//課程發佈 @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環境,能夠刪除elasticsearch-6.2.1\data\nodes目錄以徹底清除ES環境。
安裝elasticsearch-head並啓動。ide
建立索引庫
建立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是ES下的一款開源軟件,它可以同時 從多個來源採集數據、轉換數據,而後將數據發送到Eleasticsearch
中建立索引。
本項目使用Logstash將MySQL中的數據採用到ES索引中。
這裏資料給的配套文件有不少坑,我把坑都踩了一遍,下面分享解決方法。
下載Logstash6.2.1版本,和本項目使用的Elasticsearch6.2.1版本一致,版本要一致。
這裏解壓老師提供的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" }
在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 } }
說明:
一、ES採用UTC時區問題
ES採用UTC 時區,比北京時間早8小時,因此ES讀取數據時讓最後更新時間加8小時
where timestamp > date_add(:sql_last_value,INTERVAL 8 HOUR)
二、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的能力。