ElasticSearch基础篇——概念讲解,部署搭建,使用RestClient操作索引库和文档数据

目录

一、概念介绍

二、Elasticsearch的Docker容器安装

2.1拉取elasticsearch的镜像文件

2.2运行docker命令启动容器

2.3通过访问端口地址查看部署情况

三、安装Kibana容器

3.1拉取Kibana镜像容器指令(默认拉取最新版本):

3.2拉取完成后运行docker命令,部署Kibana:

3.3访问kibana提供的界面检查是否部署成功

四、配置中文分词器IK分词器

4.1在线安装IK插件

4.2离线安装

4.3通过IK分词器实现拓展词库,以及屏蔽不需要的创建词条的词语

五、elasticsearch的DSL指令使用

5.1创建索引库和mapping的DSL语句如下:

5.2其他常见索引库操作指令:

5.3使用DSL语句对文档数据进行操作

5.3.1新增文档

5.3.2查看删除文档

5.3.3修改文档

六、使用JavaRestClient实现创建、删除索引库,判断索引库是否存在

6.1、引入es的RestHighLevelClient依赖

6.2配置config文件,初始化RestHighLevelClient:

6.3创建索引库

6.4删除索引库

6.5获取索引库

七、使用RestClient操作文档数据

7.1向索引库中添加文档数据

7.2获取文档对象并解析转换为实体对象

7.3更新文档对象数据

7.4删除文档对象

7.5实现批量插入文档对象


一、概念介绍

概念:

什么是ES?

  • 从功能上来说,elasticsearchelasticsearchelasticsearch是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容,实现搜索、日志统计、分析、系统监控等功能
  • 从架构上说,elasticsearch是elastic stack的核心,负责存储、搜索、分析数据。

什么是elastic stack?

  • elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK)。被广泛应用在日志数据分析、实时监控等领域

ES能够实现对数据的快速搜索,主要原因就是它采用倒排索引的方式:

倒排索引中包含两部分内容:

  • 词条词典(Term Dictionary):记录所有词条,以及词条与倒排列表(Posting List)之间的关系,会给词条创建索引,提高查询和插入效率
  • 倒排列表(Posting List):记录词条所在的文档id、词条出现频率 、词条在文档中的位置等信息
  • 文档id:用于快速获取文档
  • 词条频率(TF):文档在词条出现的次数,用于评分

简单来说就是将一条条数据划分一个个文档,再对整个文档中的某些字段建立倒排索引,将字段按照语义划分成词语,再将每个不同的词语作为主键,对应的值就是文档的id,如下图:

ES搜索流程:

同时ES也是面向文档进行存储,可以是数据库中的一条商品数据,一个订单信息。

文档数据会被序列化为json格式后存储在elasticsearch中

索引:相同类型的文档的集合

映射( mapping ):索引中文档的字段约束信息,类似表的结构约束

下面为了加深读者对ES的认识,有关于elasticsearch和数据库的对比表格

|-----------|-------------------|----------------------------------------------------------|
| MySQL | Elasticsearch | 说明 |
| Table | Index | 索引(index),就是文档的集合,类似数据库的表(table) |
| Row | Document | 文档(Document),就是一条条的数据,类似数据库中的行(Row),文档都是JSON格式 |
| Column | Field | 字段(Field),就是JSON文档中的字段,类似数据库中的列(Column) |
| Schema | Mapping | Mapping(映射)是索引中文档的约束,例如字段类型约束。类似数据库的表结构(Schema) |
| SQL | DSL | DSL是elasticsearch提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD |

架构对比:

Mysql:擅长事务类型操作,可以确保数据的安全和一致性

Elasticsearch:擅长海量数据的搜索、分析、计算

二、Elasticsearch的Docker容器安装

2.1拉取elasticsearch的镜像文件


默认拉取最新版本,内容较大可能拉取失败,可以提前在windows下载好,上传到linux中

复制代码
docker pull docker.elastic.co/elasticsearch/elasticsearch

导入上传的镜像的tar包

复制代码
docker load -i es.tar

2.2运行docker命令启动容器

这里指定运行内存大小为512M,读者可更更具需求自行变更,详细命令解释如下

复制代码
docker run -d \
	--name es \
    -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
    -e "discovery.type=single-node" \
    -v es-data:/usr/share/elasticsearch/data \
    -v es-plugins:/usr/share/elasticsearch/plugins \
    --privileged \
    --network es-net \
    -p 9200:9200 \
    -p 9300:9300 \
elasticsearch:7.12.1

命令解释:

  • -e "cluster.name=es-docker-cluster":设置集群名称
  • -e "http.host=0.0.0.0":监听的地址,可以外网访问
  • -e "ES_JAVA_OPTS=-Xms512m -Xmx512m":内存大小
  • -e "discovery.type=single-node":非集群模式
  • -v es-data:/usr/share/elasticsearch/data:挂载逻辑卷,绑定es的数据目录
  • -v es-logs:/usr/share/elasticsearch/logs:挂载逻辑卷,绑定es的日志目录
  • -v es-plugins:/usr/share/elasticsearch/plugins:挂载逻辑卷,绑定es的插件目录
  • --privileged:授予逻辑卷访问权
  • --network es-net :加入一个名为es-net的网络中,方便之后创建Kibana容器后,两者互相连接
  • -p 9200:9200:端口映射配置

2.3通过访问端口地址查看部署情况

查询如上图所示,则表示查询成功

三、安装Kibana容器

为了实现对elasticsearch可视化操作,我们需要使用Kibana,帮助我们搭建一个页面实现对es的操作

注意:Kibana和ES版本必须一致

3.1拉取Kibana镜像容器指令(默认拉取最新版本):

复制代码
docker pull docker.elastic.co/kibana/kibana

3.2拉取完成后运行docker命令,部署Kibana:

复制代码
docker run -d \
--name kibana \
-e ELASTICSEARCH_HOSTS=http://es:9200 \
--network=es-net \
-p 5601:5601  \
kibana:7.12.1

指令解释:

  • --network es-net :加入一个名为es-net的网络中,与elasticsearch在同一个网络中

  • -e ELASTICSEARCH_HOSTS=http://es:9200":设置elasticsearch的地址,因为kibana已经与elasticsearch在一个网络,因此可以用容器名直接访问elasticsearch

  • -p 5601:5601:端口映射配置

3.3访问kibana提供的界面检查是否部署成功

四、配置中文分词器IK分词器

官方提供的分词器对中文的支持很不友好,所以我们需要引入第三方的IK分词器插件

ik分词器包含两种模式:

  • ik_smart:最少切分,粗粒度
  • ik_max_word:最细切分,细粒度

4.1在线安装IK插件

注意:IK分词器插件的版本需要对应自己的ES版本,比如我这里的7.12.1

官方插件下载地址:

复制代码
# 进入容器内部
docker exec -it elasticsearch /bin/bash

# 在线下载并安装
./bin/elasticsearch-plugin  install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.1/elasticsearch-analysis-ik-7.12.1.zip

#退出
exit
#重启容器
docker restart elasticsearch

4.2离线安装

如果提前在官方网址下载好了对应的IK分词器,可通过上传到数据卷的方式完成安装

安装插件需要知道elasticsearch的plugins目录位置,而我们用了数据卷挂载,因此需要查看elasticsearch的数据卷目录,通过下面命令查看:

复制代码
docker volume inspect es-plugins

地址:

将下载好的IK分词器的zip包解压成ik文件并上传到/var/lib/docker/volumes/es-plugins/_data文件内

重新启动容器完成插件安装

4.3通过IK分词器实现拓展词库,以及屏蔽不需要的创建词条的词语

要拓展ik分词器的词库,只需要修改一个ik分词器目录中的config目录中的IkAnalyzer.cfg.xml文件

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
	<comment>IK Analyzer 扩展配置</comment>
	<!--用户可以在这里配置自己的扩展字典 -->
	<entry key="ext_dict">ext.dic</entry>
	 <!--用户可以在这里配置自己的扩展停止词字典-->
	<entry key="ext_stopwords">stopword.dic</entry>
	<!--用户可以在这里配置远程扩展字典 -->
	<!-- <entry key="remote_ext_dict">words_location</entry> -->
	<!--用户可以在这里配置远程扩展停止词字典-->
	<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

ext.dic文本文件格式示例:直接换行输入你想要添加的扩展词汇

stopword.dic文本文件格式如上

五、elasticsearch的DSL指令使用

在创建索引库中需要了解索引库的Mapping属性

mapping是对索引库中文档的约束,常见的mapping属性包括:

  • type:字段数据类型,常见的简单类型有:
  • 字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)
  • 数值:long、integer、short、byte、double、float、
  • 布尔:boolean
  • 日期:date
  • 对象:object
  • index:是否创建索引,默认为true
  • analyzer:使用哪种分词器
    • properties:该字段的子字段

总结:

Mapping常见属性:

  • type:数据类型
  • index:是否索引
  • analyzer:分词器
  • properties:子字段

常见type类型:

  • 字符串:text、keyword
  • 数字:long、integer、short、byte、double、float
  • 布尔:boolean
  • 日期:date
  • 对象:object

5.1创建索引库和mapping的DSL语句如下:

ES中通过Restful请求操作索引库、文档,所以第一行Kibana需要发送一段请求,请求中携带DSL语句完成创建demo索引库

复制代码
PUT /demo
{
  "mappings": {
    "properties": {
      "info":{
        "type": "text",
        "analyzer": "ik_smart"
      },
      "email":{
        "type": "keyword",
        "index": "false"
      },
      "name":{
        "properties": {
          "firstName": {
            "type": "keyword"
          }
        }
      },
      // ... 略
    }
  }
}

5.2其他常见索引库操作指令:

查看索引库语法:

复制代码
GET /替换为需要查询的索引库名称

删除索引库的语法:

复制代码
DELETE /替换为需要查询的索引库名称

修改索引库语法

注意: 索引库和mapping一旦创建无法修改,但是可以添加新的字段,语法如下:

复制代码
PUT /索引库名/_mapping
{
  "properties": {
    "新字段名":{
      "type": "integer"
    }
  }
}

总结:

索引库操作

  • 创建索引库:PUT /索引库名
  • 查询索引库:GET /索引库名
  • 删除索引库:DELETE /索引库名
  • 添加字段:PUT /索引库名/_mapping

5.3使用DSL语句对文档数据进行操作

5.3.1新增文档

语法:

复制代码
POST /索引库名/_doc/文档id
{
    "字段1": "值1",
    "字段2": "值2",
    "字段3": {
        "子属性1": "值3",
        "子属性2": "值4"
    },
    // ...
}

如:

注意:

  • 插入文档时,es会检查文档中的字段是否有mapping,如果没有则按照默认mapping规则来创建索引。
  • 如果默认mapping规则不符合你的需求,一定要自己设置字段mapping

5.3.2查看删除文档

查看文档语法:

复制代码
GET /索引库名/_doc/文档id 

删除索引库的语法:

复制代码
DELETE /索引库名/_doc/文档id 

5.3.3修改文档

方式一:全量修改语法:删除原文档数据,再新增本文档数据

复制代码
PUT /索引库名/_doc/文档id
{
    "字段1": "值1",
    "字段2": "值2",
    // ... 略
}

方式二:增量修改,修改指定字段值语法:

复制代码
POST /索引库名/_update/文档id
{
    "doc": {
         "字段名": "新的值",
    }
}

六、使用JavaRestClient实现创建、删除索引库,判断索引库是否存在

6.1、引入es的RestHighLevelClient依赖

XML 复制代码
<properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.12.1</elasticsearch.version>
</properties>
<dependency>
   <groupId>org.elasticsearch.client</groupId>
   <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>

6.2配置config文件,初始化RestHighLevelClient:

XML 复制代码
@Configuration
public class ClientConfiguration {

    @Bean
    public RestHighLevelClient client() {
        return new RestHighLevelClient(RestClient
                .builder(new HttpHost("192.168.150.128", 9200, "http")
                ));
    }

}

6.3创建索引库

XML 复制代码
    @Test
    void createIndex() throws IOException {
        //1.创建Request对象
        CreateIndexRequest request = new CreateIndexRequest("demo");
        //2.准备请求的参数:DSL语句
        request.source(HOTEL_CONSTANT, XContentType.JSON);
        //3.发送请求
        client.indices().create(request, RequestOptions.DEFAULT);
    }

6.4删除索引库

XML 复制代码
@Test
    void deleteIndex() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest("demo");
        client.indices().delete(request, RequestOptions.DEFAULT);
    }

6.5获取索引库

XML 复制代码
    @Test
    void getIndex() throws IOException {
        GetIndexRequest request = new GetIndexRequest("demo");
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        log.info(exists ? "exists" : "not exists");
    }

七、使用RestClient操作文档数据

7.1向索引库中添加文档数据

XML 复制代码
   @Test
    void testAddDocument() throws IOException {
        //准备数据,数据来源于数据库
        Hotel hotel = hotelService.getById(36934L);
        //转换为文档类型
        HotelDoc hotelDoc = new HotelDoc(hotel);
        //1.准备Request对象
        IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());
        //2.准备JSON数据
        request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
        //3.发送请求
        client.index(request, RequestOptions.DEFAULT);
    }

7.2获取文档对象并解析转换为实体对象

XML 复制代码
    @Test
    void testGetDocument() throws IOException {
        //准备Request对象
        GetRequest hotel = new GetRequest("hotel", "36934");
        //发送请求得到结果
        GetResponse response = client.get(hotel, RequestOptions.DEFAULT);
        //解析结果
        String source = response.getSourceAsString();
        //反序列化的hotel对象
        HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class);
        log.info(hotelDoc.toString());
    }

7.3更新文档对象数据

XML 复制代码
    @Test
    void testUpdateDocument() throws IOException {
        //准备Request对象
        UpdateRequest request = new UpdateRequest("hotel", "36934");
        //准备请求参数
        request.doc(
                "price", "99"
        );
        //发送请求
        client.update(request, RequestOptions.DEFAULT);
    }

7.4删除文档对象

XML 复制代码
    @Test
    void testDeleteDocument() throws IOException {
        DeleteRequest request = new DeleteRequest("hotel", "36934");
        client.delete(request, RequestOptions.DEFAULT);
    }

7.5实现批量插入文档对象

XML 复制代码
    @Test
    void testBulk() throws IOException {
        //查询所有酒店数据
        List<Hotel> hotels = hotelService.list();
        //创建request对象
        BulkRequest bulkRequest = new BulkRequest();
        //将hotel对象转换为hotelDoc对象
        for (Hotel hotel : hotels) {
            HotelDoc hotelDoc = new HotelDoc(hotel);
            bulkRequest.add(new IndexRequest("hotel").id(hotelDoc.getId().toString())
                    .source(JSON.toJSONString(hotelDoc), XContentType.JSON));
        }
        //发送请求信息
        client.bulk(bulkRequest, RequestOptions.DEFAULT);
    }
相关推荐
麦兜*1 小时前
Spring Boot 企业级动态权限全栈深度解决方案,设计思路,代码分析
java·spring boot·后端·spring·spring cloud·性能优化·springcloud
B1nna2 小时前
Docker学习
学习·docker·容器
ruan1145142 小时前
MySQL4种隔离级别
java·开发语言·mysql
缘友一世2 小时前
网安系列【15】之Docker未授权访问漏洞
docker·容器
Hellyc6 小时前
基于模板设计模式开发优惠券推送功能以及对过期优惠卷进行定时清理
java·数据库·设计模式·rocketmq
lifallen6 小时前
Paimon LSM Tree Compaction 策略
java·大数据·数据结构·数据库·算法·lsm-tree
hdsoft_huge6 小时前
SpringBoot 与 JPA 整合全解析:架构优势、应用场景、集成指南与最佳实践
java·spring boot·架构
百锦再7 小时前
详细解析 .NET 依赖注入的三种生命周期模式
java·开发语言·.net·di·注入·模式·依赖
程序员的世界你不懂7 小时前
基于Java+Maven+Testng+Selenium+Log4j+Allure+Jenkins搭建一个WebUI自动化框架(2)对框架加入业务逻辑层
java·selenium·maven
有没有没有重复的名字8 小时前
线程安全的单例模式与读者写者问题
java·开发语言·单例模式