博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Springboot实战系列]整合ElasticSearch实现数据模糊搜索(Logstash同步Mysql数据)
阅读量:7154 次
发布时间:2019-06-29

本文共 4900 字,大约阅读时间需要 16 分钟。

前言

本文介绍了如何整合搜索引擎elasticsearch与springboot,对外提供数据查询接口。

业务介绍

我的需要对mysql数据库内存储的京东商品进行模糊查询(模仿淘宝商品搜索),所以选择了将数据导入elasticsearch随后使用他来进行关键词查询。前端只需发送用户搜索的关键词和分页参数(可选),即可返回商品数据(json格式)

开发环境

组件介绍:

  • elasticsearch:搜索引擎,用于存储待搜索数据
  • logstash:用于将mysql中的商品数据同步到搜索引擎中
  • elasticsearch-head(可选):elasticsearch可视化工具
  • kibana(可选):elasticsearch可视化工具

本文测试环境:

  • springboot:1.5.16
  • elasticsearch:2.3.5(springboot1.5仅支持2.x的es)
  • logstash:6.5.4

开发步骤

使用Docker部署elasticsearch

  • docker下一键启动es,可根据需要的版本号对语句做修改
sudo docker run -it --rm --name elasticsearch -d -p 9200:9200 -p 9300:9300 elasticsearch:2.3.5复制代码

注意到该命令:

  • --rm参数:容器终止后销毁
  • -d:后台进程
  • -p 9200:9200 -p 9300:9300:开放了9200端口和9300端口

得到如图:

此时打开网页localhost:9200即可查看状态,显示类似为:

{  "name" : "Ant-Man",  "cluster_name" : "elasticsearch",  "version" : {    "number" : "2.3.5",    "build_hash" : "90f439ff60a3c0f497f91663701e64ccd01edbb4",    "build_timestamp" : "2016-07-27T10:36:52Z",    "build_snapshot" : false,    "lucene_version" : "5.5.0"  },  "tagline" : "You Know, for Search"}复制代码

注意:docker的es默认对0.0.0.0公网开放

下载并使用logstash并导入数据

本文中要导入的是pm_backend下的表pm_jd_item内的全部京东商品数据

详细步骤参考:

最终编写的jdbc.conf为:

schedule => "* * * * *"默认为每分钟同步一次

input {  jdbc {    jdbc_connection_string => "jdbc:mysql://localhost:3306/pm_backend"    jdbc_user => "root"    jdbc_password => "xxxxxxxxxx"    jdbc_driver_library => "xxxxxxxx/mysql-connector-java-5.1.6.jar"    jdbc_driver_class => "com.mysql.jdbc.Driver"    jdbc_paging_enabled => "true"    jdbc_page_size => "5000"    statement=> "select * from pm_jd_item"    schedule => "* * * * *"    type => "pm_jd_item"  }}output {  elasticsearch {    hosts => "localhost:9200"    index => "pm_backend"    document_type => "%{type}"    document_id => "%{id}"  }  stdout {    codec => json_lines  }}复制代码

在logstash目录下执行命令,完成数据的导入:

bin/logstash -f jdbc.conf复制代码

得到如图:

同步完成后,使用elasticsearch-head查看(或者用kibana,请随意):

整合进springboot

  1. 添加pom.xml
org.elasticsearch
elasticsearch
2.4.6
org.springframework.boot
spring-boot-starter-data-elasticsearch
org.springframework.data
spring-data-elasticsearch
复制代码
  1. 修改application.properties
# elasticsearchspring.data.elasticsearch.cluster-name=elasticsearch#节点地址,多个节点用逗号隔开spring.data.elasticsearch.cluster-nodes=127.0.0.1:9300#spring.data.elasticsearch.local=falsespring.data.elasticsearch.repositories.enable=true复制代码
  1. 在需要进行搜索的实体类上添加@Document、@Id、@Field等标注,本例为JdItem.java
@Document(indexName = "pm_backend", type = "pm_jd_item")public class JdItem implements Serializable {    @Id    private Integer id;    @Field(type = FieldType.Long)    private Long itemId;    @Field(type = FieldType.Long)    private Long categoryId;    @Field(type = FieldType.String)    private String name;复制代码
  1. 添加JdItemRepository继承ElasticsearchRepository
public interface JdItemRepository extends ElasticsearchRepository
{}复制代码
  1. 编写JdItemController中的查询接口findJdItemByName

代码截取自个人项目,仅供参考!

/**     * 根据商品名在pm_jd_item中搜索商品     * @param itemName     * @param startRow     * @param pageSize     * @return     */    @ApiOperation(value="查询商品", notes="查询商品")    @RequestMapping(value = "/findJdItemByName", method = {RequestMethod.GET})    public ResponseData
> findJdItemByName( @ApiParam("用户输入的商品名") @RequestParam(value = "itemName") String itemName, @ApiParam("页码索引(默认为0)") @RequestParam(value = "startRow", required = false, defaultValue = "0") int startRow, @ApiParam("每页的商品数量(默认为10)") @RequestParam(value = "pageSize", required = false, defaultValue = "10") int pageSize ){ ResponseData
> responseData = new ResponseData<>(); try { FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery().add(QueryBuilders.matchPhraseQuery("name", itemName), ScoreFunctionBuilders.weightFactorFunction(100)).scoreMode("sum").setMinScore(10); Pageable pageable = new PageRequest(startRow, pageSize); SearchQuery searchQuery = new NativeSearchQueryBuilder().withPageable(pageable).withQuery(functionScoreQueryBuilder).build(); Page
jdItems = jdItemRepository.search(searchQuery); // Page分页getTotalPages()返回了应有的页数,临时放在errorMsg传给前端 responseData.jsonFill(1, String.valueOf(jdItems.getTotalPages()), jdItems.getContent()); } catch (Exception e) { e.printStackTrace(); responseData.jsonFill(2, e.getMessage(), null); } return responseData; }}复制代码
  1. 运行springboot

调用findJdItemByName接口,得到:

整合分词器功能

请参考:

参考

Docker安装ES & Kibana:

Elasticsearch之使用Logstash导入Mysql数据:

关注我

我是蛮三刀把刀,后端开发。主要关注后端开发,数据安全,爬虫等方向。

来微信和我聊聊:yangzd1102

Github个人主页:

原创博客主要内容

  • Java知识点复习全手册
  • Leetcode算法题解析
  • 剑指offer算法题解析
  • Python爬虫相关技术实战
  • 后端开发相关技术实战
  • SpringCloud实战

个人公众号:Rude3Knife

如果文章对你有帮助,不妨收藏起来并转发给您的朋友们~

转载地址:http://wylgl.baihongyu.com/

你可能感兴趣的文章
linux中的strip命令简介------给文件脱衣服【转】
查看>>
算法笔记_184:历届试题 约数倍数选卡片(Java)
查看>>
1082 线段树练习 3 区间查询与区间修改
查看>>
(二)EasyUI 使用——常用组件
查看>>
Linux下的搜索命令grep(转)
查看>>
Linux内核通知链机制的原理及实现
查看>>
分压、分流原理
查看>>
IE浏览器上传文件时本地路径变成”C:\fakepath\”的问题
查看>>
单用户模式找回root密码
查看>>
.NET:race conditions
查看>>
WiFi基本知识 .
查看>>
C++ 类
查看>>
抽象类和接口的区别
查看>>
Extjs 常用正则式
查看>>
详细解析WPF中的应用程序模型
查看>>
css开头的全局标准代码
查看>>
背包学习————01背包
查看>>
【转载】VIEW层AJAX提交表单到Controller的实体(AJAX传递序列化的输入元素
查看>>
文字即艺术
查看>>
【Programming Clip】位运算的应用
查看>>