在前面文章中主要是对ES的一个入门,那么在生产环境中结合业务ES到底是如何使用的呢?
本文将讲解电商品平台商城系统如何使用ES做商品搜索功能。
- 如何达到更高效的分词 ;
- 怎么分词 ;
- 分词器的使用 ;
- 源码工程讲解 ;
- MySQL -> 到ES数据导入 ;
存储以MySQL+ElasticSearch为例,实际业务中要实现商品搜索。
- 建立好相关业务表, 这里数据库以MySQL为例 ;
- 在数据操作的时候同时操作ES ;
1.环境准备
- 必需-安装ElasticSearch、
- 必需-ik分词器 注意这与 ES版本需保持一致。
相关文章
2.运行环境
- ElasticSearch 7.4.0
- kibana 7.4.0
- IK分词器 7.4.0 (官方传送门)
- JDK 1.8
- Maven 3.6
- SpringBoot 2.3.0
- 模板引擎(thymeleaf)
3.MySQL业务表
这里主要涉及3张核心表,“商品表”、“分类表”、“品牌表” (仅实战测试使用)
3.1商品表
CREATE TABLE `sku_info` (
`id` bigint(20) NOT NULL COMMENT '规格商品ID',
`spu_id` bigint(20) NOT NULL COMMENT 'spu id',
`title` varchar(256) NOT NULL DEFAULT '' COMMENT '标题',
`goods_name` varchar(128) NOT NULL DEFAULT '' COMMENT '商品名称',
`price` decimal(14,2) NOT NULL DEFAULT '0.00' COMMENT '价格',
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态 1-正常;2-下架;3-删除',
`image_url` varchar(200) NOT NULL DEFAULT '0' COMMENT '主图地址',
`category_id` bigint(20) NOT NULL COMMENT '类目ID',
`category_name` varchar(200) NOT NULL DEFAULT '' COMMENT '分类名称',
`brand_id` bigint(20) NOT NULL COMMENT '品牌ID',
`brand_name` varchar(128) NOT NULL DEFAULT '' COMMENT '品牌名称',
`stock_num` int(10) NOT NULL DEFAULT '0' COMMENT '库存数量',
`sales_num` int(10) NOT NULL DEFAULT '0' COMMENT '销售数量',
`appraise_num` int(10) NOT NULL DEFAULT '0' COMMENT '评价数量',
`shop_name` varchar(128) NOT NULL DEFAULT '' COMMENT '店铺名称',
`spec` varchar(1000) NOT NULL DEFAULT '' COMMENT '规格JSON',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `spu_id` (`spu_id`) USING BTREE,
KEY `category_id` (`category_id`) USING BTREE,
KEY `brand_id` (`brand_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='测试商品表';
规格字段spec 存储示例,商品直接不同,是动态变化的。
这里使用JSON存的,实际业务建议扩展表。
{
"CPU型号": "骁龙865",
"屏幕尺寸": "6.67",
"运行内存": "12GB",
"颜色": "天云黑"
}
3.2分类表
CREATE TABLE `category_info` (
`id` bigint(20) NOT NULL COMMENT '分类ID',
`category_name` varchar(200) NOT NULL DEFAULT '' COMMENT '分类名称',
`alias_name` varchar(200) NOT NULL DEFAULT '' COMMENT '别名',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='测试商品表';
3.3品牌表
CREATE TABLE `brand_info` (
`id` bigint(20) NOT NULL COMMENT '品牌ID',
`brand_name` varchar(128) NOT NULL DEFAULT '' COMMENT '品牌名称',
`alias_name` varchar(128) NOT NULL DEFAULT '' COMMENT '别名',
`english_name` varchar(128) NOT NULL DEFAULT '' COMMENT '英文名',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='测试商品表';
SQL脚本下载地址
链接:https://pan.baidu.com/s/1y2H8a_DNPzkQ2m11sgDQog 密码:76mj
4.源码工程
- common 包,存放了一些公共常量,工具类等
- controller 接口
- dao mapper与实体类
- model 转换对象
- repository 使用data-elasticsearch与ES对应
- service 接口与实现
- templates 基于templates实现的页面。这里没有用前后分离。
- static 页面所需的一些静态依赖文件。
源码工程下载地址
链接:https://pan.baidu.com/s/16oefp-mdDEQ1syrpZiP65A
密码:w8z6
注:若存在链接失效,请私信联系看到必回谢谢
这里使用的与elasticsearch整合使用的是spring-boot-starter-data-elasticsearch
详见Demo:xxx
5.功能介绍
在功能介绍之前我们需要先建立好ES的索引,在上文已经建立好了3张MySQL数据表。
MySQL表 | 源码ES对应类 | ES索引 |
---|---|---|
sku_info | SkuInfoModel | sku_info |
category_info | CategoryInfo | category_info |
brand_info | SkuInfo | brand_info |
与ES对应的Model类截图
注:这里使用的与elasticsearch整合使用的是spring-boot-starter-data-elasticsearch,
所以在启动项目的时候,索引就会根据上图与ES对应的model类的配置,创建索引。
5.1数据导入到ES
数据据导入的入口在 SkuImportController
SkuInfoModel类 ( 与ES对应的model类 )
注:ES可以是聚合Mysql多张表的数据存储。使用ES就是为了查询,一切为了查询。需要先冗余为了查询,后更新的方式。
- 注意规格数据导入时的转换,JSON转换成Map。如果存的是扩展表,也可转成Map存到ES,主要是为了ES规范搜索。
MySQL => ElasticSearch 数据同步方式
- 功能上可以在后台系统新增或编辑商品的时候同时操作ES的新增或更新。
- 解耦的方式可以通过比如定时脚本通过时间断点新增或更新数据。分页查询表内 update_time>= 某个时间点。
- 第三方的同步组件比如 : canal (阿里MySQL binlog 增量订阅&消费组件)
5.2IK分词器设置
为了提高匹配度,建议将品牌与分类的关键字导入到IK分词器自定义词库中
# 品牌名称
SELECT brand_name from brand_info;
# 品牌别名
SELECT alias_name from brand_info;
# 分类名称
SELECT category_name from category_info;
# 分类别名
SELECT alias_name from category_info;
对于新增的词库只对后续添加的数据生效,若想让之前的数据生效 可以参考 IK分词器新增词库使历史数据生效
生产环境一般采用,晚间或者流量较小的时间,分批更新的处理方式
5.3商品功能实现
为了方便实现,没有用前后分离方式,在源码包 templates 下search.html 既商品搜索功能实现的页面
源码工程入口在SearchController
分页查询后端接口方法
com.example.controller.SearchController#search
5.3.1商品搜索实现方法
5.3.2构建查询对象方法
5.3.3关键字、分类、品牌、规格搜索条件
6.源码工程启动
1.首先导入表与数据到 MySQL (SQL脚本下载地址 | 密码:76mj)
2.修改配置文件application.properties [ MySQL 与 es 配置成自己的服务 ]
3.启动程序
4.执行导入数据功能 MySQL => Elasticsearch
http://localhost:8821//sku/import-to-es
访问商品查询页
http://localhost:8821/search?keywords=%E5%8D%8E%E4%B8%BA%E6%89%8B%E6%9C%BA