使用Spring Boot + Elasticsearch + Logstash 完毕史籍查询检索就业
前边咱们先容了Spring Boot 整合 Elasticsearch 完毕数据查询检索的功能,在实质神态中,咱们的数据一般存储在数据库中,而且跟着业务的发送,数据也会随时变化。
那么怎样保证数据库中的数据与Elasticsearch存储的索引数据保捏一致呢? 最原始的有设想即是:当数据发生增更正操作时同步更新Elasticsearch。然而这么的设想耦合太高。接下来咱们先容一种卓越精真金不怕火的数据同步方式:Logstash 数据同步。
迷魂香烟 一、Logstash简介 1.什么是Logstashlogstash是一个开源的就业器端数据责罚器具。精真金不怕火来说,即是一根具备及时数据传输才气的管说念,雅致将数据信息从管说念的输入端传输到管说念的输出端;与此同期这根管说念还不错让你凭据我方的需求在中间加上滤网,Logstash提供里许多功能无边的滤网以温顺你的多样愚弄场景。
Logstash常用于日记系统中作念日记汇注树立,最常用于ELK中算作日记网罗器使用。
迷水商城 2.Logstash的架构旨趣Logstash的基本历程架构:input=》 filter =》 output 。
input(输入):汇注多样样式,大小和起原数据,从各个就业器中网罗数据。常用的有:jdbc、file、syslog、redis等。
迷水商城filter(过滤器)雅致数据责罚与转念。主如果将event通过output发出之前对其完毕的某些责罚功能。
output(输出):将咱们过滤出的数据保存到那些数据库和联系存储中,。
迷水商城

3.Logstash怎样与Elasticsearch数据同步
实质神态中,咱们不成能通过手动添加的方式将数据插入索引库,是以需要借助第三方器具,将数据库的数据同步到索引库。此时,Logstash出现了,它不错将不同数据库的数据同步到Elasticsearch中。保证数据库与Elasticsearch的数据保捏一致。

迷水商城
当今相沿数据库与ES数据同步的插件有许多,个东说念主觉得Logstash是无边同步mysql数据到es的插件中,最褂讪况兼最容易建设的一个。
二、安设LogstashLogstash的使用身手也很精真金不怕火,底下锤真金不怕火一下,Logstash是怎样使用的。需要阐述的是:这里以windows 环境为例,演示Logstash的安设和建设。
1.下载Logstash最初,下载对应版块的Logstash包,不错通过上头提供下载elasticsearch的地址进行下载,完成后解压。
迷水商城

迷水商城
上头是Logstash解压后的目次,咱们需要怜惜是bin目次中的实施文献和config中的建设文献。一般分娩情况下,会使用Linux就业器,况兼会将Logstash建设成自启动的就业。这里测试的话,径直启动。
2.建设Logstash接下来,建设Logstash。需要咱们编写建设文献,性药购买凭据官网和网上提供的建设文献,将其进行修改。
第一步:在Logstash根目次下创建mysql文献夹,添加mysql.conf建设文献,建设Logstash需要的相应信息,具体建设如下:
迷水商城input { stdin { } jdbc { # mysql数据库聚拢 jdbc_connection_string => "jdbc:mysql://localhost:3306/book_test?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC" # mysqly用户名和密码 jdbc_user => "root" jdbc_password => "root" # 驱动建设 jdbc_driver_library => "C:\Users\Administrator\Desktop\logstash-7.5.1\mysql\mysql-connector-java-8.0.20.jar" # 驱动类名 jdbc_driver_class => "com.mysql.cj.jdbc.Driver" #jdbc_paging_enabled => "true" #jdbc_page_size => "50000" jdbc_default_timezone => "Asia/Shanghai" # 实施指定的sql文献 statement_filepath => "C:\Users\Administrator\Desktop\logstash-7.5.1\mysql\sql\bookquery.sql" use_column_value => true # 是否将字段名转念为小写,默许true(如果稀有据序列化、反序列化需求,提议改为false); lowercase_column_names => false # 需要纪录的字段,用于增量同步,需是数据库字段 tracking_column => updatetime # Value can be any of: numeric,timestamp,Default value is "numeric" tracking_column_type => timestamp # record_last_run前次数据存放位置; record_last_run => true #上一个sql_last_value值的存放文献旅途, 必须要在文献中指定字段的开动值 last_run_metadata_path => "C:\Users\Administrator\Desktop\logstash-7.5.1\mysql\sql\logstash_default_last_time.log" # 是否撤废last_run_metadata_path的纪录,需要增量同步时此字段必须为false; clean_run => false # 树立监听 各字段含义 分 时 天 月 年 ,默许沿途为*代表含义:每分钟齐更新 schedule => "* * * * *" # 索引类型 type => "id" } } output { elasticsearch { #es就业器 hosts => ["10.2.1.231:9200"] #ES索引称呼 index => "book" #自增ID document_id => "%{id}" } stdout { codec => json_lines } }
第二步:将mysql-connector-java.jar 拷贝到前边建设的目次下。上头的mysql.conf建设的是:C:\Users\Administrator\Desktop\logstash-7.5.1\mysql\
迷水商城mysql-connector-java-8.0.20.jar。那么jar包拷贝到此目次下即可:
迷水商城迷水商城

上头是mysql的驱动,如果是sqlserver数据库,下载SqlServer对应的驱动即可。摈弃的位置要与mysql.conf 建设文献中的jdbc_driver_library 地址保捏一致。
第三步:创建sql目次,创建bookquery.sql文献用于保存需要实施的sql 剧本。示例代码如下:

select * from book where updatetime >= :sql_last_value order by updatetime desc
这里使用的增量更新,是以使用:sql_last_value 纪录上一次纪录的临了工夫。
3.启动Logstash参预logstash的bin目次,实施如下敕令:
logstash.bat -f C:\Users\Administrator\Desktop\logstash-7.5.1\mysql\mysql.conf
启动获胜之后,Logstash就会自动定时将数据写入到Elasticsearch。如下图所示:

同步完成后,咱们使用Postman查询Elasticsearch,考据索引是否齐创建获胜。在postman中,发送 Get 肯求:
http://10.2.1.231:9200/book/_search 。复返祛除如下图所示:

迷水商城
不错看到,数据库中的数据也曾通过Logstash同步至Elasticsearch。阐述Logstash建设获胜。
三、创建查询就业数据同步完成后,接下来咱们使用Spring Boot 构建Elasticsearch查询就业。最初创建Spring Boot神态并整合Elasticsearch,这个之前齐也曾先容过,不了了的一又友不错看我之前的著述。
接下来演示怎样封装好意思满的数据查询就业。
迷水商城 1.数据实体@Document( indexName = "book" , replicas = 0) public class Book { @Id private Long id; @Field(analyzer = "ik_max_word",type = FieldType.Text) private String bookName; @Field(analyzer = "ik_max_word",type = FieldType.Text) private String author; private float price; private int page; @Field(type = FieldType.Date,format = DateFormat.custom,pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") private Date createTime; @Field(type = FieldType.Date,format = DateFormat.custom,pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") private Date updateTime; @Field(analyzer = "ik_max_word",type = FieldType.Text) private String category; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public int getPage() { return page; } public void setPage(int page) { this.page = page; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } public Book(){ } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } }2.肯求封装类
public class BookQuery { public String category; public String bookName; public String author; public int priceMin; public int priceMax; public int pageMin; public int pageMax; public String sort; public String sortType; public int page; public int limit; }3.创建Controller为止器
@RestController public class ElasticSearchController { @Autowired private ElasticsearchRestTemplate elasticsearchRestTemplate; /** * 查询信息 * @param * @return */ @PostMapping(value = "/book/query") public JSONResult query(@RequestBody BookQuery bookQuery){ Query query= getQueryBuilder(bookQuery); SearchHits<Book> searchHits = elasticsearchRestTemplate.search(query, Book.class); List<SearchHit<Book>> result = searchHits.getSearchHits(); return JSONResult.ok(result); } public Query getQueryBuilder(BookQuery query) { BoolQueryBuilder builder = boolQuery(); // 匹配器 恶浊查询部分,分析器使用ik (ik_max_word) List<QueryBuilder> must = builder.must(); if (query.getBookName()!=null && !query.getBookName().isEmpty()) must.add(wildcardQuery("bookName", "*" +query.getBookName()+ "*")); if (query.getCategory()!=null && !query.getCategory().isEmpty()) must.add(wildcardQuery("category", "*" +query.getCategory()+ "*")); if (query.getAuthor()!=null && !query.getAuthor().isEmpty()) must.add(wildcardQuery("author", "*" +query.getAuthor()+ "*")); // 筛选器 精准查询部分 List<QueryBuilder> filter = builder.filter(); // 限制查询 if (query.getPriceMin()>0 && query.getPriceMax()>0) { RangeQueryBuilder price = rangeQuery("price").gte(query.getPriceMin()).lte(query.getPriceMax()); filter.add(price); } // 限制查询 if (query.getPageMin()>0 && query.getPageMax()>0) { RangeQueryBuilder page = rangeQuery("page").gte(query.getPageMin()).lte(query.getPageMax()); filter.add(page); } // 分页 PageRequest pageable = PageRequest.of(query.getPage() - 1, query.getLimit()); // 排序 SortBuilder sort = SortBuilders.fieldSort("price").order(SortOrder.DESC); //树立高亮效力 String preTag = "<font color='#dd4b39'>";//google的色值 String postTag = "</font>"; HighlightBuilder.Field highlightFields = new HighlightBuilder.Field("category").preTags(preTag).postTags(postTag); Query searchQuery = new NativeSearchQueryBuilder() .withQuery(builder) .withHighlightFields(highlightFields) .withPageable(pageable) .withSort(sort) .build(); return searchQuery; } }4.测测考据
启动神态,在Postman中,肯求
迷水商城http://localhost:8080/book/query 接口查询册本信息数据。稽查接口复返情况。

咱们看到接口获胜复返数据。阐述数据查询就业创建获胜。
临了
以上,咱们就把使用Spring Boot + Elasticsearch + Logstash 完毕好意思满的数据查询检索就业先容结束。
迷水商城