一: 安装和配置
安装Elasticsearch
安装kibana
安装ik分词器
二:学习目标
独立编写数据导入功能
独立实现基本搜索
独立实现页面分页
独立实现结果排序
1.2.1.新建一个用户leyou
出于安全考虑,elasticsearch默认不允许以root账号运行。
1.2.2.上传安装包,并解压
1.2.3.修改配置
我们进入config目录:cd config
jvm.options
Elasticsearch基于Lucene的,而Lucene底层是java实现,因此我们需要配置jvm参数。
elasticsearch.yml
(Lucene不是一个完整的全文索引应用,而是是一个用Java写的全文索引引擎工具包,它可以方便的嵌入到各种应用中实现针对应用的全文索引/检索功能。)
1.3.运行
进入elasticsearch/bin目录,可以看到下面的执行文件:
1.3.1.错误1:内核过低
我们使用的是centos6,其linux内核版本为2.6。而Elasticsearch的插件要求至少3.5以上版本。不过没关系,我们禁用这个插件即可。
修改elasticsearch.yml文件,在最下面添加如下配置:
1.3.2.错误2:文件权限不足
我们用的是leyou用户,而不是root,所以文件权限不足。
首先用root用户登录。
1.3.3.错误3:线程数不够
1.3.4.错误4:进程虚拟内存
1.3.5.重启终端窗口
所有错误修改完毕,一定要重启你的 Xshell终端,否则配置无效。
1.3.6.启动
再次启动,终于成功了!
1.4.安装kibana
1.4.1.什么是Kibana?
Kibana是一个基于Node.js的Elasticsearch索引库数据统计工具,可以利用Elasticsearch的聚合功能,生成各种图表,如柱形图,线状图,饼图等。
而且还提供了操作Elasticsearch索引数据的控制台,并且提供了一定的API提示,非常有利于我们学习Elasticsearch的语法。
(简单的说 Node.js 就是运行在服务端的 JavaScript。Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。)
(JavaScript 是一种脚本,一门编程语言,它可以在网页上实现复杂的功能,网页展现给你的不再是简单的静态信息,而是实时的内容更新,交互式的地图,2D/3D 动画,滚动播放的视频等等。JavaScript 怎能缺席。)
1.5.安装ik分词器
Lucene的IK分词器早在2012年已经没有维护了,现在我们要使用的是在其基础上维护升级的版本,并且开发为ElasticSearch的集成插件了,与Elasticsearch一起维护升级,版本也保持一致,最新版本:6.3.0
独立编写数据导入功能
独立实现基本搜索
独立实现页面分页
独立实现结果排序
1.索引库数据导入
昨天我们学习了Elasticsearch的基本应用。今天就学以致用,搭建搜索微服务,实现搜索功能。
1.1.创建搜索服务
1.2.索引库数据格式分析
接下来,我们需要商品数据导入索引库,便于用户搜索。
那么问题来了,我们有SPU和SKU,到底如何保存到索引库?
1.2.1.以结果为导向
因此,搜索的结果是SPU,即多个SKU的集合。
既然搜索的结果是SPU,那么我们索引库中存储的应该也是SPU,但是却需要包含SKU的信息。
1.2.2.需要什么数据
1.2.3.最终的数据结构
我们创建一个类,封装要保存到索引库的数据,并设置映射属性:
@Document(indexName = "goods", type = "docs", shards = 1, replicas = 0)
public class Goods {
@Id
private Long id; // spuId
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String all; // 所有需要被搜索的信息,包含标题,分类,甚至品牌
@Field(type = FieldType.Keyword, index = false)
private String subTitle;// 卖点
private Long brandId;// 品牌id
private Long cid1;// 1级分类id
private Long cid2;// 2级分类id
private Long cid3;// 3级分类id
private Date createTime;// 创建时间
private List price;// 价格
@Field(type = FieldType.Keyword, index = false)
private String skus;// sku信息的json结构
private Map specs;// 可搜索的规格参数,key是参数名,值是参数值
}
1.3.商品微服务提供接口
索引库中的数据来自于数据库,我们不能直接去查询商品的数据库,因为真实开发中,每个微服务都是相互独立的,包括数据库也是一样。所以我们只能调用商品微服务提供的接口服务。
先思考我们需要的数据:
SPU信息
SKU信息
SPU的详情
商品分类名称(拼接all字段)
再思考我们需要哪些服务:
第一:分批查询spu的服务,已经写过。
第二:根据spuId查询sku的服务,已经写过
第三:根据spuId查询SpuDetail的服务,已经写过
第四:根据商品分类id,查询商品分类名称,没写过
第五:根据商品品牌id,查询商品的品牌,没写过
因此我们需要额外提供一个查询商品分类名称的接口。
1.3.1.商品分类名称查询
controller:
1.3.2.编写FeignClient
1.3.2.1.问题展现
操作leyou-search工程
1.4.导入数据
导入数据只做一次,以后的更新删除等操作通过消息队列来操作索引库
1.4.1.创建GoodsRepository
java代码:
public interface GoodsRepository extends ElasticsearchRepository
}
1.4.2.创建索引
我们新建一个测试类,在里面进行数据的操作:
1.4.3.导入数据
导入数据其实就是查询数据,然后把查询到的Spu转变为Goods来保存,因此我们先编写一个SearchService,然后在里面定义一个方法, 把Spu转为Goods
2.实现基本搜索
2.1.页面分析
2.1.1.页面跳转
2.1.2.发起异步请求
要想在页面加载后,就展示出搜索结果。我们应该在页面加载时,获取地址栏请求参数,并发起异步请求,查询后台数据,然后在页面渲染。
(同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。
异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。)
通过钩子函数created,在页面加载时获取请求参数,并记录下来。
created(){
// 判断是否有请求参数
if(!location.search){
return;
}
// 将请求参数转为对象
const search = ly.parse(location.search.substring(1));
// 记录在data的search对象中
this.search = search;
// 发起请求,根据条件搜索
this.loadData();
}
2.2.后台提供搜索接口
2.2.1.controller
2.2.2.service
2.2.3.测试
2.3.页面渲染
2.3.1.保存搜索结果
2.3.2.循环展示商品
2.3.3.多sku展示
2.3.3.1.分析
2.3.3.2.初始化sku
2.3.3.3.多sku图片列表
2.3.4.展示sku其它属性
3.页面分页效果
刚才的查询中,我们默认了查询的页码和每页大小,因此所有的分页功能都无法使用,接下来我们一起看看分页功能条该如何制作。
这里要分两步,
第一步:如何生成分页条
第二步:点击分页按钮,我们做什么
3.1.如何生成分页条
3.1.1.需要的数据
分页数据应该是根据总页数、当前页、总条数等信息来计算得出。
当前页:肯定是由页面来决定的,点击按钮会切换到对应的页
总页数:需要后台传递给我们
总条数:需要后台传递给我们
3.1.2.后台提供数据
3.1.3.页面计算分页条
3.2.点击分页做什么
点击分页按钮后,自然是要修改page的值
所以,我们在上一页、下一页按钮添加点击事件,对page进行修改,在数字按钮上绑定点击事件,点击直接修改page:
JavaScript绑定事件的3种方式
第1种:使用内联
第2种:使用.onclick的方式
第3种:使用事件监听addEventListener的方式(前面2种只能绑定1种,后面可以绑定多种)
参考链接:https://juejin.im/post/6844903720136736775
3.3.页面顶部分页条
4.排序(作业)
4.1.页面搜索排序条件
这是用来做排序的,默认按照综合排序。点击新品,应该按照商品创建时间排序,点击价格应该按照价格排序。因为我们没有统计销量和评价,这里咱们以新品和价格为例,进行讲解,做法是想通的。
排序需要知道两个内容:
排序的字段
排序的方式
4.2.后台添加排序逻辑
接下来,后台需要接收请求参数中的排序信息,然后在搜索中加入排序的逻辑。
现在,我们的请求参数对象SearchRequest中,只有page、key两个字段。需要进行扩展:
然后在搜索业务逻辑中,添加排序条件:
注意,因为我们存储在索引库中的的价格是一个数组,因此在按照价格排序时,会进行智能处理:
如果是价格降序,则会把数组中的最大值拿来排序
如果是价格升序,则会把数组中的最小值拿来排序