提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录- 前言
- 一、ElasticSearch相关概念
- 1. 基本概念
- 2. ElasticSearch有什么用?
- 二、ElasticSearch安装
- 1. docker镜像下载
- 2. 安装es容器
- 3. 开启远程连接
- 三、项目整合ElasticSearch
前言
Elasticsearch 是一个分布式的免费开源搜索和分析引擎,适用于包括文本、数字、地理空间、结构化和非结构化数据等在内的所有类型的数据。Elasticsearch 在 Apache Lucene 的基础上开发而成,由 Elasticsearch N.V.(即现在的 Elastic)于 2010 年首次发布。Elasticsearch 以其简单的 REST 风格 API、分布式特性、速度和可扩展性而闻名,是 Elastic Stack 的核心组件;Elastic Stack 是一套适用于数据采集、扩充、存储、分析和可视化的免费开源工具。人们通常将 Elastic Stack 称为 ELK Stack(代指 Elasticsearch、Logstash 和 Kibana),目前 Elastic Stack 包括一系列丰富的轻量型数据采集代理,这些代理统称为 Beats,可用来向 Elasticsearch 发送数据。
1. 基本概念
Elasticsearch是面向文档(document oriented)的,这意味着它可以存储整个对象或文档(document)。 然而它不仅仅是存储,还会索引(index)每个文档的内容使之可以被搜索。在Elasticsearch中,你可以对 文档(而非成行成列的数据)进行索引、搜索、排序、过滤。
用Mysql这样的数据库存储就会容易想到建立一张User表,有很多的字段等,在Elasticsearch里这就是一个文档,当然这个文档会属于一个User的类型,各种各样的类型存在于一个索引当中。
关系数据库 ⇒ 数据库 ⇒ 表 ⇒ 行 ⇒ 列(Columns) Elasticsearch ⇒ 索引(Index) ⇒ 类型(type) ⇒ 文档(Docments) ⇒ 字段(Fields)2. ElasticSearch有什么用?
ElasticSearch在速度和扩展性上方面都表现出色, 而且还能够索引多种类型的内容, 这意味着其可用于多种用例:
- 应用程序搜索
- 网站搜索
- 企业搜索
- 日志处理和分析
- 基础设施指标和容器检测
- 地理空间数据分析和可视化
- 安全分析
- 业务分析
本项目中使用Docker安装
1. docker镜像下载docker pull elasticsearch:5.6.82. 安装es容器
docker run -di --name=es -p 9200:9200 -p 9300:9300 elasticsearch:5.6.8
9200端口(Web管理平台端口) 9300(服务默认端口)
浏览器输入地址访问: http://110.42.216.234:9200 (注意: 请修改成自己的虚拟机ip)
上面完成安装后,es并不能正常使用,elasticsearch从5版本以后默认不开启远程连接,程序直接连接会报如下错误:
failed to load elasticsearch nodes : org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available: [{#transport#-1}{5ttLpMhkRjKLkvoY7ltUWg} {192.168.211.132}{192.168.211.132:9300}]
我们需要修改es配置开启远程连接,代码如下:
登录容器
docker exec -it es /bin/bash
进入config目录
cd config
调用ls命令可以看到如下文件
elasticsearch.yml log4j2.properties scripts
修改elasticsearch.yml文件
vi elasticsearch.yml
修改如下图:
同时添加下面一行代码:
cluster.name: my-elasticsearch
重启docker
docker restart es
三、项目整合ElasticSearch
pom.xml文件中添加ElasticSearch的依赖
org.springframework.boot spring-boot-starter-data-elasticsearch
配置文件 search-service.yml 中ElasticSearch的相关配置:
server:
port: 9006
其他配置...
spring:
data:
elasticsearch:
cluster-name: elasticsearch
cluster-nodes: 192.168.220.110:9300
elasticsearch:
rest:
uris: 192.168.220.110:9200
编写启动类 SearchApplication.java
package com.gyh.legou.search;
@SpringBootApplication //spring boot
@EnableDiscoveryClient //将微服务注册到注册中心
@EnableFeignClients //通过feign调用其他微服务
@EnableCircuitBreaker //开启熔断,微服务容错保护
public class SearchApplication {
public static void main(String[] args) {
SpringApplication.run(SearchApplication.class, args);
}
}
我们创建一个类,封装要保存到索引库的数据,并设置映射属性:
package com.gyh.legou.search.po;
@Data
@document(indexName = "goods_legou", type = "docs_legou", 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是参数名,值是参数值
}
一些特殊字段解释:
- all:用来进行全文检索的字段,里面包含标题、商品分类信息
- price:价格数组,是所有sku的价格集合。方便根据价格进行筛选过滤
- skus:用于页面展示的sku信息,不索引,不搜索。包含skuId、image、price、title字段
- specs:所有规格参数的集合。key是参数名,值是参数值。
例如:我们在specs中存储 内存:4G,6G,颜色为红色,转为json就是:
{
"specs":{
"内存":[4G,6G],
"颜色":"红色"
}
}
当存储到索引库时,elasticsearch会处理为两个字段:
- specs.内存:[4G,6G]
- specs.颜色:红色
创建 GoodsRepository 类
package com.gyh.legou.search.dao; public interface GoodsDao extends ElasticsearchRepository{ }
接下来导入数据。导入数据其实就是查询数据,然后把查询到的Spu转变为Goods来保存,因此我们先编写一个 IndexService,然后在里面定义一个方法, 把Spu转为Goods
package com.gyh.legou.search.service;
@Service
public class IndexService {
@Autowired
private GoodsDao goodsDao;
@Autowired
private CategoryClient categoryClient;
@Autowired
private SpecParamClient specParamClient;
@Autowired
private SkuClient skuClient;
@Autowired
private SpuDetailClient spuDetailClient;
public Goods buildGoods(Spu spu) {
//准备数据
//商品分类名称
List names = this.categoryClient.queryNameByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));
String all = spu.getTitle() + " " + StringUtils.join(names, " ");
//sku集合
List skus = skuClient.selectSkusBySpuId(spu.getId());
//处理sku
//把商品价格取出单独存放,便于展示
List prices = new ArrayList<>();
List
然后编写一个测试类,循环查询Spu,然后调用IndexService中的方法,把SPU变为Goods,然后写入 索引库:
package com.gyh.legou.search;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SearchApplication.class)
public class ESLoadDataTest {
@Autowired
private IndexService indexService;
@Autowired
private SpuClient spuClient;
@Autowired
private GoodsDao goodsDao;
@Test
public void loadData() {
// 查询spu
// PageResult result = this.goodsClient.querySpuByPage(page,rows, true, null);
// List spus = result.getItems();
List spus = spuClient.selectAll();
// spu转为goods
List goods = spus.stream().map(spu -> this.indexService.buildGoods(spu)).collect(Collectors.toList());
// 把goods放入索引库
goodsDao.saveAll(goods);
}
}



