elasticsearch
结构
- elasticsearch 简介
- 什么是搜索引擎
- 为什么是elasticsearch
- 核心概念
- 核心对象
- 倒排索引
- 动手实践
- 版本匹配
- 安装工作
- 代码实践
- 数据同步
- 定时同步
- 实时同步
- 总结
一、elasticsearch 简介
结构
- 什么是搜索引擎
- 为什么是elasticsearch
二、核心概念
结构
- 核心对象
- 倒排索引
三、动手实践
结构
- 版本匹配
- 安装工作
- 代码实践
3.1、版本匹配
第二列SpringDataElasticSearch是pom依赖的版本;
第三列ElasticSearch是linux上安装的es中间件版本;
第五列SpringBoot是pom依赖的版本。
3.2、安装工作
docker elastisearch
- 查看镜像版本
- 拉取镜像
- 启动镜像
- 测试
docker elasticsearch-head(es的管理页面)
- 拉取镜像
- 启动镜像
- 测试
- 修改配置
- 重启
安装 ik 分词器
- 离线安装
- 在线安装
docker elasticsearch
cat /proc/sys/vm/max_map_count
sysctl -w vm.max_map_count=262144
查看镜像版本
docker search elasticsearch
拉取镜像
docker pull elasticsearch:tag
启动镜像
docker run --name elasticsearch -d -e ES_JAVA_OPTS=“-Xms512m -Xmx512m” -e “discovery.type=single-node” -p 6002:9200 -p 6022:9300 elasticsearch:6.8.12
测试
访问 ip:6002
出现一下界面是 成功
docker elasticsearch-head
#1、拉取镜像
docker pull mobz/elasticsearch-head:5
#2、创建容器
docker create --name elasticsearch-head -p 6003:9100 mobz/elasticsearch-head:5
#3、启动容器
docker start elasticsearch-head
#4、测试 浏览器访问 ip:6003
#5、是因为 elasticsearch 与 elasticsearch-head 是前后端分离的,所以存在跨域的问题
#5.1、修改docker中elasticsearch的elasticsearch.yml文件
docker exec -it elasticsearch /bin/bash (进不去使用容器id进入)
vi config/elasticsearch.yml
#添加内容
http.cors.enabled: true
http.cors.allow-origin: "*"
#退出并重启服务
exit
docker restart 容器id
ik 分词器
- 离线安装
- 在线安装
网上说ik 分词器好像没什么用
离线安装
下载分词器压缩包
下载地址:
https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.7.0/elasticsearch-analysis-ik-7.7.0.zip
将IK分词器上传到/tmp目录中(xftp)
将分词器安装进容器中
#将压缩包移动到容器中
docker cp /tmp/elasticsearch-analysis-ik-7.7.0.zip elasticsearch:/usr/share/elasticsearch/plugins
#进入容器
docker exec -it elasticsearch /bin/bash
#创建目录
mkdir /usr/share/elasticsearch/plugins/ik
#将文件压缩包移动到ik中
mv /usr/share/elasticsearch/plugins/elasticsearch-analysis-ik-7.7.0.zip /usr/share/elasticsearch/plugins/ik
#进入目录
cd /usr/share/elasticsearch/plugins/ik
#解压
unzip elasticsearch-analysis-ik-7.7.0.zip
#删除压缩包
rm -rf elasticsearch-analysis-ik-7.7.0.zip
在线安装
#1、进入容器
docker exec -it elasticsearch /bash
#2、安装 ik 分词器
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v[tag]/elasticsearch-analysisc-ik-[tag].zip
3.3、实践
结构
- elasticsearch-springboot
elasticsearch-springboot
结构
- 添加依赖
- 添加配置
- 代码编写
添加依赖
- elasticsearch
- mysql
依赖
<!--elasticsearch-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
</dependency>
添加配置
elasticsearch:
rest:
uris: http://localhost:9200
connection-timeout: 5
read-timeout: 10
代码编写
- 创建文档实体类
- elasticsearch的curd
创建文档实体类
注解说明:
- @Document :用来标识文档实体类,indexName 属性用来指定索引名称;createIndex = false 标识不自动创建索引,默认true,生产环境建议关闭
- @Id : 用来指定索引的id字段
- @Field : 用来标识文档的字段,store 用来设置是否持久化;analyzer 用来指定索引的分词器;searchAnalyzer 用来指定查询时的分词器,如果没有则使用analyzer
@Data
@Accessors(chain = true)
@Document(indexName = "article", createIndex = false)
public class Article {
@Id
private Long id;
@Field(store = true, searchAnalyzer = "ik_smart", analyzer = "ik_smart")
private String author;
@Field(store = true, searchAnalyzer = "ik_smart", analyzer = "ik_smart")
private String title;
@Field(store = true, searchAnalyzer = "ik_max_word", analyzer = "ik_max_word")
private String content;
}
elasticsearch的curd 方式
- ElasticsearchRepository
- ElasticsearchRestTemplate
ElasticsearchRepository 与 ElasticsearchRestTemplate:
- ElasticsearchRepository 其实底层是调用的 ElasticsearchRestTemplate。
- ElasticsearchRestTemplate 底层其实是对 RestHighLevelClient (Elasticsearch 官方提供的java客户端)的近一步封装。
- 既生瑜何生亮:
- 1、实际上是spring 想要保持 spring data 的初衷,提供统一的接口(Reposity),屏蔽具体的数据层的实现。ElasticsearchRepository 负责对文档的各种 curd 操作;而 ElasticsearchRestTemplate 用来做更底层的操作,比如负责索引的维护,更复杂的查询等。
ElasticsearchRepository
就像jpa的JpaRepository,这是springboot 专门为 elasticsearch 的 repository。
使用方法:
创建对应的实体对应的Repository,并继承 ElasticsearchRepository。
ElasticsearchRepository 的继承关系:
代码实战:
- 实体repository
- controller
实体repository
public interface ArticleRepository extends ElasticsearchRepository<Article, Long> {
Page<Article> findByTitleLike(String title, Pageable page);
}
controller
@ApiOperation("新增Article")
@PostMapping("saveArticle")
public Result<Iterable<Article>> createArticle(@RequestBody List<Article> articles) {
return Result.success(articleRepository.saveAll(articles));
}
@PutMapping("/update-repo")
@ApiOperation("通过Repository更新")
public Result<Article> update(@RequestBody Article article) {
return Result.success(articleRepository.save(article));
}
@DeleteMapping("del-repo")
@ApiOperation("通过Repository删除")
public Result<Boolean> delete(@RequestParam Long id) {
articleRepository.deleteById(id);
return Result.success(Boolean.TRUE);
}
@DeleteMapping("del-temp")
@ApiOperation("通过Template删除")
public Result<String> delete(@RequestParam String id) {
return Result.success(elasticsearchRestTemplate.delete( Article.class,id));
}
@ApiOperation("根据标题搜索")
@GetMapping("/search-title")
public Result<Page<Article>> searchByTitle(String title) {
Pageable pageable = PageRequest.of(0,10); // page 从第 0 页开始
return Result.success(articleRepository.findByTitleLike(title, pageable));
}
ElasticsearchRestTemplate
springboot 提供的 template,类似 redisTemplate,RabbitTemplate。
- 对象注入
- api使用
对象注入
@Resource
private ElasticsearchRestTemplate elasticsearchRestTemplate;
api 使用
@DeleteMapping("del-temp")
@ApiOperation("通过Template删除")
public Result<String> delete(@RequestParam String id) {
return Result.success(elasticsearchRestTemplate.delete( Article.class,id));
}
@GetMapping("/count")
@ApiOperation("统计数量")
public Result<Long> count(String keyWord) {// page 从第 0 页开始
Query query = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.multiMatchQuery(keyWord, "author","title","content"))
.build();
return Result.success(elasticsearchRestTemplate.count((CriteriaQuery) query, Article.class));
}
四、数据同步
通常情况下,elasticsearch 不生产数据,一般会先将数据同步到 elasticsearch,然后由 elasticsearch 完成搜索。数据同步到 elasticsearch 分为两种类型:一种是全量同步;另一种是增量同步。全量同步通常只会执行一次,即在初始化的时候同步进行的。数据库之后发生的增加,删除,修改的操作的时候,只会将变化同步过去,这就是增量同步。增量同步可以才用定时同步或者实时同步的方案
结构
- 定时同步
- 实时同步
4.1、定时同步
只需要编写定时任务,每隔一段时间就将该时间段产生的变化同步到 elasticsearch 即可。 elastic 官方提供的 logstash 采用的就是定时同步的方案。我们可以设置同步的频率和同步的sql语句。需要注意的是边界的确定,如果逻辑不严谨,则可能出现重复数据或者数据缺失问题。
4.2、实时同步
以mysql 为例,实时同步方案一般都是基于 binlog 实现的。binlog 是mysql 记录数据发生增加,删除,修改操作的二进制文件。它可以用来查看数据库的变更历史,数据库的增量备份和恢复,以及 mysql 的主/从 复制。canal 就是基于 binlog实现的。
五、总结
- 搜索引擎分为目录搜索引擎,全文搜索引擎,元搜索引擎,垂直搜索引擎。
- elasticsearch 核心对象包括:index,type,document,field,mapping
- elasticsearch 适合做搜索引擎的原因在于 倒排索引
- springboot 提供两种访问 elasticsearch 的方式 :elasticsearchRepository 和 elasticsearchRestTemplate
- 数据同步到 elasticsearch 通常有两种方案:定时任务同步,实时同步