【ElasticSearch】Elastic Search入门及Spring Boot整合ES

一、Elastic Search 基础

1.1 什么是ElasticSearch

Elasticsearch 是位于 Elastic Stack 核心的分布式搜索和分析引擎, 是一个基于 Apache Lucene (TM),分布式的使用 REST 接口的搜索引擎,Elasticsearch 不仅仅是 Lucene 和全文搜索引擎,它还提供:

  • 分布式的实时文件存储,每个字段都被索引并可被搜索
  • 实时分析的分布式搜索引擎
  • 可以扩展到上百台服务器,处理 PB 级结构化或非结构化数据

1.2 基本概念

  1. 索引index: 类似于数据库的表
  2. 类型type:类似于表的逻辑类型,用于区分不同的索引类型
  3. 文档document:类似于数据库的记录行,是我们搜索的核心目标,以Json数据格式存在,是可以被索引的一个基础数据单位
  4. 字段fields:类似于数据库的列,是文档的一个个不同的属性
  5. 映射mapping:相当于表结构的定义,如有哪些字段、是什么数据类型等
  6. 近实时NRT:near real time,当创建了新的文档或索引的时候,如果用户请求搜索,可以以接近实时的时间返回搜索结果。
  7. 节点node:即分布式架构下的一个服务器节点
  8. shard replica:数据分片与备份的概念

1.3 倒排索引

一般索引是以key寻找value,倒排索引则相反,提取value中的各个属性值(关键字),由关键字为依据去返回包含这些关键字的记录的key,与常规索引相反,因此称为倒排索引。

二、Elastic Search 安装与配置

环境:MacOS Monterey
版本:为了方便开发的其他部分选用了6.8.6版本

2.1 安装ES

官网链接。直接到官网下载对应系统和版本的包,注意ES的版本比较敏感,需要对应好后端的Spring Boot的版本进行下载。

启动前需要进入config目录下,修改elasticsearch.yml文件中的部分设置,首先是集群名和节点名:

# ---------------------------------- Cluster -----------------------------------
#
# Use a descriptive name for your cluster:
#
cluster.name: xxx-cluster
#
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
#
node.name: xxx-node

然后是日志和数据的地址:

# ----------------------------------- Paths ------------------------------------
#
# Path to directory where to store the data (separate multiple locations by comma):
#
path.data: /Users/lr/Workspace/software/es/data
#
# Path to log files:
#
path.logs: /Users/lr/Workspace/software/es/data/log
#

最后是IP和端口:

# Set the bind address to a specific IP (IPv4 or IPv6):
#
network.host: 0.0.0.0 
#
# Set a custom port for HTTP:
#
# http.port: 9200 端口默认是9200

主要是这三部分,如果有额外需要再添加。

2.2 启动ES

通过bin目录下的可执行文件elasticsearch即可启动服务,控制台可以看到日志输出,添加参数-d后台启动。
在MacOS下启动遇到了一些与jvm相关的问题,需要到config目录下修改jvm.options文件
首先是与GC相关的,不知道为什么原始配置不能启动,网上求解无果后尝试修改了GC,绕开了报错:

## G1GC Configuration
# NOTE: G1 GC is only supported on JDK version 10 or later
# to use G1GC, uncomment the next two lines and update the version on the
# following three lines to your version of the JDK
# 10-13:-XX:-UseConcMarkSweepGC
# 10-13:-XX:-UseCMSInitiatingOccupancyOnly
14-:-XX:+UseG1GC
14-:-XX:G1ReservePercent=25
14-:-XX:InitiatingHeapOccupancyPercent=30

14-:-XX:+UseG1GC 这个部分原来没记错的话应该是-XX:+UseConcMarkSweepGC,但是原始的配置没法启动。
另一个是在该配置文件末尾:

# temporary workaround for C2 bug with JDK 10 on hardware with AVX-512
10-:-XX:UseAVX=2

启动时提示是未知的配置项,注释掉之后能正常启动

2.3 Chrome 插件监控ES

使用的插件名为Multi ElasticSearch Head,如果ES正确启动,打开该插件可以看到这样的画面:
在这里插入图片描述
上面有包括host、ip和版本的信息,右上角有集群的健康情况。通过插件还可以直接添加和删除索引。

2.4 分析器的使用

ES内置了五种分词器:

  • standard:默认的分词方式,单词会被独立出来,全部转换为小写
  • simple:按照非字母分词,全部转换为小写
  • whitespace:按照空格分词,大小写保持
  • stop:去除无意义的单词,如the, a, an等
  • keyword:不做分词,把整个文本作为一个独立的关键词

standard和simple的区别在于,standard会按照空格、标点等进行拆分,而simple则会在一切非字母的字符处做拆分,如don't在standard下是一个整体,而在simple中会从'处拆分为两个部分。

内置的五种分词器均不支持中文分词,因此这里需要安装ik分词器,安装过程简单此处不详细叙述,下载对应版本的ik,解压到es的插件目录并重启es即可。

2.5 向ES发送分析请求

在这里插入图片描述
其中analyzer指定了使用的分词器,text则是分析的内容。发送请求得到的结果如下:

{
     "tokens": [
          {
               "token": "今天",
               "start_offset": 0,
               "end_offset": 2,
               "type": "CN_WORD",
               "position": 0
          },
          {
               "token": "的",
               "start_offset": 2,
               "end_offset": 3,
               "type": "CN_CHAR",
               "position": 1
          },
          {
               "token": "风儿",
               "start_offset": 3,
               "end_offset": 5,
               "type": "CN_WORD",
               "position": 2
          },
          {
               "token": "甚是",
               "start_offset": 5,
               "end_offset": 7,
               "type": "CN_WORD",
               "position": 3
          },
          {
               "token": "喧嚣",
               "start_offset": 7,
               "end_offset": 9,
               "type": "CN_WORD",
               "position": 4
          }
     ]
}

三、Spring Boot整合ES

3.1 依赖

pom.xml增添如下依赖项:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>

这里我还尝试了以下HighLevelRestClient,再添加以下依赖:

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
        </dependency>

注意HighLevelRestClient的版本与ES保持一致

3.2 配置

application.yml文件添加如下配置,这些配置在后续版本中是弃用的,但是6.8.6版本仍然可以使用:

  data:
    elasticsearch:
      cluster-name: laros-elasticsearch # es版本6.8.6可以继续使用该形式
      cluster-nodes: 'localhost:9300'

这里注意ES与http的交互接口是9200,但是默认与Java交互的接口是9300(来自某篇被遗忘的博客),之前曾因为配置写了9200而无法连接。

3.3 Spring Boot配置类

如果要使用RestHighLevelClient,则需要编写如下配置类:

@Configuration
public class ESConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        return new RestHighLevelClient(
                RestClient.builder(new HttpHost("127.0.0.1", 9200, "http"))
        );
    }
}

3.4 发送请求建立索引

这里跟随教程使用了ElasticsearchTemplate并自己又尝试用了RestHighLevelClient。先简单做个尝试,后续再深入研究。

首先是需要一个索引对应的module类:

@Document(indexName = "EsIdx", type = "_doc") // 7.x版本后不再支持type属性
public class EsIdx {
    @Id
    Long indexId;

    @Field
    private String indexName;

    @Field
    private Integer counts;

    @Field
    private Float price;

    @Field
    private String infos;

记得添加getter和setter,以及构造器等。然后写一个Controller把两个Bean注入进去,部分注解省略了

public class HelloController {
    private final ElasticsearchTemplate esTemp;

    private final RestHighLevelClient esClient;
}
首先是使用RestHighLevelClient,操作过程如下:
    @RequestMapping("/createIndex")
    public Object createIndex(){
        EsIdx idx = new EsIdx(1001L, "测试索引", 10, 20.9f, "这是一条测试索引");
        String jsonIdx = JsonUtils.objectToJson(idx);
        IndexRequest req = new IndexRequest("stu", "EsIdx", "1");
        req.source(jsonIdx, XContentType.JSON);
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.add(req);

        try {
            esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
            return JsonResultObject.ok();![在这里插入图片描述](https://img-blog.csdnimg.cn/523c1688c35742ed8f62c9b2f4950d21.png#pic_center)

        } catch (IOException e) {
            e.printStackTrace();
            return JsonResultObject.errorMsg(e.toString());
        }
    }

这里使用时遇见过一个错误:IndexRequest的source方法是个有重载的方法,使用JSON数据格式时要有第二个参数来指定类型,否则会报错

第二种:
    @RequestMapping("/tempCreateIndex")
    public Object tempCreateIndex(){
        esTemp.createIndex(EsIdx.class);
        return JsonResultObject.ok();
    }

看起来会简单不少,但是也少了很多可以控制的东西,实际学习过程中发现,这里createIndex会报错,提示索引名要全小写,一开始猜测是与module类上的注解有关,但是实际修改测试后发现并不是。因为时间比较紧张这里先挖个坑,暂时使用第一种方式继续学习,后续有时间再回头研究两者的区别和正确的使用方法。

3.5 测试

发送请求到对应的接口,返回200说明成功

在这里插入图片描述
然后到Chrome的插件查看是不是有新数据进来了
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值