elasticsearch

elasticsearch

结构

  • elasticsearch 简介
    • 什么是搜索引擎
    • 为什么是elasticsearch
  • 核心概念
    • 核心对象
    • 倒排索引
  • 动手实践
    • 版本匹配
    • 安装工作
    • 代码实践
  • 数据同步
    • 定时同步
    • 实时同步
  • 总结

一、elasticsearch 简介

结构

  • 什么是搜索引擎
  • 为什么是elasticsearch

二、核心概念

结构

  • 核心对象
  • 倒排索引

三、动手实践

结构

  • 版本匹配
  • 安装工作
  • 代码实践

3.1、版本匹配

第二列SpringDataElasticSearch是pom依赖的版本;
第三列ElasticSearch是linux上安装的es中间件版本;
第五列SpringBoot是pom依赖的版本。

image-20230219141231475

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

出现一下界面是 成功

image-20230219143011630


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

image-20230219144737340

#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

image-20230219145122247


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 的继承关系:

image-20230219200434544

代码实战:

  • 实体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 通常有两种方案:定时任务同步,实时同步
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值