SpringCloud(十)——ElasticSearch简单了解(一)初识ElasticSearch和RestClient

这篇具有很好参考价值的文章主要介绍了SpringCloud(十)——ElasticSearch简单了解(一)初识ElasticSearch和RestClient。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 初始ElasticSearch

1.1 ElasticSearch介绍

Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。充分利用Elasticsearch的水平伸缩性,能使数据在生产环境变得更有价值。Elasticsearch 的实现原理主要分为以下几个步骤,首先用户将数据提交到Elasticsearch 数据库中,再通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据,当用户搜索数据时候,再根据权重将结果排名,打分,再将返回结果呈现给用户。

Elasticsearch是与名为Logstash的数据收集和日志解析引擎以及名为Kibana的分析和可视化平台一起开发的。这三个产品被设计成一个集成解决方案,称为“Elastic Stack”(以前称为“ELK stack”)。

Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。Elasticsearch是分布式的,这意味着索引可以被分成分片,每个分片可以有0个或多个副本。每个节点托管一个或多个分片,并充当协调器将操作委托给正确的分片。再平衡和路由是自动完成的。相关数据通常存储在同一个索引中,该索引由一个或多个主分片和零个或多个复制分片组成。一旦创建了索引,就不能更改主分片的数量。

Elasticsearch使用Lucene,并试图通过JSON和Java API提供其所有特性。它支持facetting和percolating,如果新文档与注册查询匹配,这对于通知非常有用。另一个特性称为“网关”,处理索引的长期持久性;例如,在服务器崩溃的情况下,可以从网关恢复索引。Elasticsearch支持实时GET请求,适合作为NoSQL数据存储,但缺少分布式事务。

ElasticSearch中有一些新的概念,这里我们对应于MySQL数据库中的一些概念来对其进行讲解,可能会有更好的效果。

MySQL ElasticSearch 说明
Table Index 索引,就是文档的集合,类似于数据库中的表
Row Document 文档,就是一条条的数据,类似数据库中的一行,文档都是JSON形式
Column Field 字段,就是JSON中的字段名,类似数据库中的列
Schema Mapping Mapping是索引中文档的约束,例如字段类型约束,类似数据库的表结构
SQL DSL DSL是ElasticSearch提供的JSON风格的请求语句,用于操作ElasticSearch

1.2 安装并运行ElasticSearch

因为我们还需要部署kibana容器,因此需要让es和kibana容器互联。这里先创建一个网络:

docker network create es-net

然后使用elasticsearch的7.12.1版本的镜像,直接pull。

pull elasticsearch:7.12.1

如果需要运行es并进行单点部署,那么命令如下:

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的网络中
  • -p 9200:9200:端口映射配置,暴露的HTTP请求的端口
  • -p 9300:9300:端口映射配置,暴露ElasticSearch互联的端口

访问虚拟机地址的9200端口,如果出现以下页面,说明配置成功,
SpringCloud(十)——ElasticSearch简单了解(一)初识ElasticSearch和RestClient,JavaEE,spring cloud,elasticsearch,spring

1.3 运行kibana

kibana可以给我们提供一个ElasticSearch的可视化界面,方便我们学习,运行如下代码表示运行一个kibana,

docker run -d \
--name kibana \
-e ELASTICSEARCH_HOSTS=http://es:9200 \
--network=es-net \
-p 5601:5601  \
kibana:7.12.1
  • -e ELASTICSEARCH_HOSTS=http://es:9200":设置elasticsearch的地址,因为kibana已经与elasticsearch在一个网络,因此可以用容器名直接访问elasticsearch
  • --network es-net :加入一个名为es-net的网络中,与elasticsearch在同一个网络中
  • -p 5601:5601:端口映射配置

之后等待其部署完毕后,访问虚拟机的5601端口,发现乳腺的界面表示启动成功,
SpringCloud(十)——ElasticSearch简单了解(一)初识ElasticSearch和RestClient,JavaEE,spring cloud,elasticsearch,spring

1.4 安装IK分词器

在ElasticSearch中,我们常常需要用到分词的操作,英文还好,其自带的就可以进行分词,但是中文,其只会按照逐字的方式对词进行划分,这显然是并不友好的,因此,我们需要安装一个专门的分词器来对中文进行分词。

安装IK分词器的步骤如下:

# 进入容器内部
docker exec -it es /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 es

打开kibana中的目录,找到Dev tools,
SpringCloud(十)——ElasticSearch简单了解(一)初识ElasticSearch和RestClient,JavaEE,spring cloud,elasticsearch,spring
在其中输入DSL查询语句进行分词。

# 测试分词器
POST /_analyze
{
  "text": "我们ikun不惹事,但也不怕事",
  "analyzer": "ik_smart"#分词的模式
}

分词结果如下:
SpringCloud(十)——ElasticSearch简单了解(一)初识ElasticSearch和RestClient,JavaEE,spring cloud,elasticsearch,spring
还有一种分词模式是 ik_max_word ,能够按照最细粒度去进行分词,更加占用内存空间。

2. 操作索引库和文档

2.1 mapping属性

mapping属性相当于就是数据库的字段约束,主要常用的mapping属性约束如下:

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

2.2 创建索引库

了解了mapping约束后,我们就可以开始创建索引了,创建索引库的语法如下:

PUT /索引库名

创建索引也就是创建每一个字段的约束条件,与数据库类似,我们创建一个名为 ikun 的索引,索引如下:

PUT /ikun
{
  "mappings": {
    "properties": {
      "info": {
        "type": "text",
        "analyzer": "ik_smart"
      },
      "email": {
        "type": "keyword",
        "index": false
      },
      "name": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "keyword"
          },
          "lastName": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

执行后显示的结果如下,表明创建成功:

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "ikun"
}

2.3 对索引库的查、删、改

查询索引库的语法如下:

GET /索引库名

删除索引库的语法如下:

DELETE /索引库名

需要注意的是,索引库一经创建就不允许进行修改,但是,我们可以对原来的索引库进行新增,语法如下:

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

2.4 操作文档

在索引库中插入文档相当于在数据库的表结构中增加一行数据。

新增文档的DSL语法如下:

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

文档id如果没有指定的话,会随机生成。

比如我们对上面创建的索引库进行新增如下:

POST /ikun/_doc/1
{
  "info": "我们ikun不惹事,但也不怕事",
  "email": "snow@gmail.com",
  "name": {
    "firstName": "i",
    "lastName": "kun"
  }
}

查看文档的语法为:

GET /ikun/_doc/1

删除文档的语法为:

DELETE /ikun/_doc/1

修改文档有两种方法。

一种是全量修改,其会首先找到旧的文档,将旧的文档进行删除,然后将修改的再添加进去。如果旧的文档不存在,这种方法还是会进行新增。语法如下:

PUT /索引库名/_doc/1
{
  "字段1": "值1",
  "字段2": "值2",
}

还有一种是增量修改,只会修改指定的字段,语法如下:

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

比如我们修改上面的文档1的邮箱可以为:

POST /ikun/_update/1
{
  "doc": {
    "email": "snowsnow@gmail.com"
  }
}

3. RestClient

ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求发送给ES,这里我们要学习的就是java中调用RestClient。

我们的数据库数据结构如下所示,
SpringCloud(十)——ElasticSearch简单了解(一)初识ElasticSearch和RestClient,JavaEE,spring cloud,elasticsearch,spring
故我们构建索引库的代码如下:

PUT /hotel
{
  "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
      "name": {
        "type": "text",
        "analyzer": "ik_max_word",
        "copy_to": "all"
      },
      "address": {
        "type": "keyword",
        "index": false
      },
      "price": {
        "type": "integer"
      },
      "score": {
        "type": "integer"
      },
      "brand": {
        "type": "keyword",
        "copy_to": "all"
      },
      "city": {
        "type": "keyword"
      },
      "starName": {
        "type": "keyword"
      },
      "bussiness": {
        "type": "keyword",
        "copy_to": "all"
      },
      "location": {
        "type": "geo_point"
      },
      "pic": {
        "type": "keyword",
        "index": false
      },
      "all": {
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

在ElasticSearch中,对经纬度专门指定了一个结构 geo_point ,这里面能够存储经度和纬度的结构,除此之外,上面的 copy_to 字段是对字段进行联合索引的时候使用的。比如在上面我们需要对 name 属性和 brand 属性就行搜索,一般是先搜索符合的 name ,再到结果集里面搜索符合条件的 brand ,这样显然非常麻烦,而加入了一个 copy_to 字段后,便可以将该属性复制一份到 all 属性中,当然, all 属性并不存在与索引的 suorce 里面,此后,如果我们需要查询符合条件的 namebrand 时,只需要查询 all 属性即可。

那怎么在java中操作RestClient客户端呢?

3.1 初始化RestClient

首先是引入依赖,需要引入如下的依赖:

<properties>
    <java.version>1.8</java.version>
    <elasticsearch.version>7.12.1</elasticsearch.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>7.12.1</version>
</dependencies>

由于SpringBoot在父maven中已经定义了ElasticSearch的版本号,所以改版本的时候需要在 properties 标签中覆盖父pom定义的版本号。

之后就是初始化RestClient了。

如果我们对每一个类都要创建和销毁RestClient客户端的话,那就显得太过麻烦了,我们可以将创建和销毁写作一个Ioc切面,在每一个Bean创建之前切入并创建客户端,在每一个Bean执行后切入并销毁客户端,具体代码如下:

public class HotelIndexTest {
    private RestHighLevelClient restHighLevelClient;

    @BeforeEach
    void setup(){
        this.restHighLevelClient = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.59.233:9200")
        ));
    }

    @AfterEach
    void teardown() throws IOException {
        this.restHighLevelClient.close();
    }
}

3.2 操作索引库

  • 创建索引库
        @Test
        void createHotelIndex() throws IOException {
            //1.创建Request对象,索引坤名称为ikun
            CreateIndexRequest request = new CreateIndexRequest("ikun");
            //2.准备请求参数,即DSL语句,第一个参数为DSL语句,第二个参数指定为JSON形式
            request.source("{\n" +
                    "  \"mappings\": {\n" +
                    "    \"properties\": {\n" +
                    "      \"kunName\": {\n" +
                    "        \"type\": \"text\",\n" +
                    "        \"analyzer\": \"ik_smart\"\n" +
                    "      }\n" +
                    "    }\n" +
                    "  }\n" +
                    "}", XContentType.JSON);
            //3.发送请求
            restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        }
    
  • 删除索引库
        @Test
        void DeleteHotelIndex() throws IOException {
            //1.创建Request对象
            DeleteIndexRequest request = new DeleteIndexRequest("ikun");
            restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
        }
    
  • 判断索引库是否存在
    	@Test
        void ExistHotelIndex() throws IOException {
            //1.创建Request对象
            GetIndexRequest request = new GetIndexRequest("ikun");
            boolean exist = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
            System.out.println(exist);
        }
    

3.3 操作文档

  • 增加文档

    如果我们需要用RestClient进行文档的增加,那么首先我们需要的就是类型转换,我们的文档内容肯定是从数据库中进行获取,但是,数据库中的数据与索引库的数据还是有一点不一样的,那就是经纬度。在数据库中,我们定义的是经度以及纬度,但是,在索引库中,我们定义的是一个数据结构 geo_point ,里面包含了经度以及纬度,所以,我们首先定义一个与索引库结构一致的类,如下:

    @Data
    @NoArgsConstructor
    public class HotelDoc {
        private Long id;
        private String name;
        private String address;
        private Integer price;
        private Integer score;
        private String brand;
        private String city;
        private String starName;
        private String business;
        private String location;
        private String pic;
    
        public HotelDoc(Hotel hotel) {
            this.id = hotel.getId();
            this.name = hotel.getName();
            this.address = hotel.getAddress();
            this.price = hotel.getPrice();
            this.score = hotel.getScore();
            this.brand = hotel.getBrand();
            this.city = hotel.getCity();
            this.starName = hotel.getStarName();
            this.business = hotel.getBusiness();
            this.location = hotel.getLatitude() + ", " + hotel.getLongitude();
            this.pic = hotel.getPic();
        }
    }
    

    之后,便可以读取数据库中的信息对索引库进行文档的增加了,增加的代码如下,

    @SpringBootTest
    public class HotelIndexTest {
        @Autowired
        private IHotelService hotelService;
    
        private RestHighLevelClient restHighLevelClient;
    
        @Test
        void AddHotelDocument() throws IOException {
            //1.根据ID查询酒店数据
            Hotel hotel = hotelService.getById(61083L);
            //2.转换为文档类型
            HotelDoc hotelDoc = new HotelDoc(hotel);
            //3.准备Request对象,其参数只接受String
            IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
            //4.准备JSON文档
            request.source(JSON.toJSONString(hotelDoc),XContentType.JSON);
            //5.发送请求
            restHighLevelClient.index(request, RequestOptions.DEFAULT);
        }
    
        @BeforeEach
        void setup(){
            this.restHighLevelClient = new RestHighLevelClient(RestClient.builder(
                    HttpHost.create("http://192.168.59.233:9200")
            ));
        }
    
        @AfterEach
        void teardown() throws IOException {
            this.restHighLevelClient.close();
        }
    }
    
  • 查询文档

    	@Test
        void FindHotelDocument() throws IOException {
            //1.准备Request对象,其参数只接受String
            GetRequest request = new GetRequest("hotel", "61083");
            //2.发送请求得到响应
            GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
            //3.解析相应结果,即将source字段解析为json格式的字符串
            String json = response.getSourceAsString();
            //4.将JSON格式的字符串解析为相应的对象
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            System.out.println(hotelDoc);
        }
    
  • 更新文档

        @Test
        void UpdateHotelDocument() throws IOException {
            //1.准备Request对象,其参数只接受String
            UpdateRequest request = new UpdateRequest("hotel", "61083");
            //2.准备参数,特别注意,这里是逗号,没有冒号!!
            request.doc(
                    "price", "1001",
                    "startName", "四钻"
            );
            //3.发送请求
            restHighLevelClient.update(request, RequestOptions.DEFAULT);
        }
    
  • 删除文档

        @Test
        void UpdateHotelDocument() throws IOException {
            //1.准备Request对象,其参数只接受String
            DeleteRequest request = new DeleteRequest("hotel", "61083");
            //2.发送请求
            restHighLevelClient.delete(request, RequestOptions.DEFAULT);
        }
    
  • 批量新增数据文章来源地址https://www.toymoban.com/news/detail-688339.html

        @Test
        void AddMoreDocument() throws IOException {
            //1.批量查询数据库中的信息
            List<Hotel> hotels = hotelService.list();
            //2.创建Request
            BulkRequest request = new BulkRequest();
            //3.准备参数,添加多个新增的Request
            for(Hotel hotel: hotels){
                HotelDoc hotelDoc = new HotelDoc(hotel);
                request.add(new IndexRequest("hotel")
                        .id(hotel.getId().toString())
                        .source(JSON.toJSONString(hotelDoc),XContentType.JSON));
            }
            //4.发送请求
            restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
        }
    

到了这里,关于SpringCloud(十)——ElasticSearch简单了解(一)初识ElasticSearch和RestClient的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 初识SpringCloud

    一、软件架构演进 单体架构 垂直架构 分布式架构 SOA架构 微服务架构 二、微服务架构 2.1 微服务理念 \\\"微服务”一词源 于 Martin Fowler的名为 Microservices的博文,可以在他的官方博客上找到http://martinfowler.com/articles/microservices.html 微服务是系统架构上的一种设计风格,它的主旨是将

    2024年02月01日
    浏览(30)
  • 【SpringCloud入门】-- 初识Eureka注册中心

    目录 1.SpringCloudEureka简介 2.什么是CAP原则? 3.注册中心的概念? 4.SpringCloud其他注册中心 5.搭建Eureka注册中心 6.eureka的配置(主要是server,instance,client) 7.eureka集群概念 8.eureka集群搭建 1.SpringCloudEureka简介 注册发现中心Eureka,意为“发现了”。它是Netflix公司开发的一款基于RES

    2024年02月09日
    浏览(44)
  • 【多线程】初识线程,基础了解

    目录 认识线程     概念         什么是线程?         为啥要有线程         进程和线程的区别         Java 的线程 和 操作系统线程 的关系     创建线程         1.继承 Thread 类         2.实现 Runnable 接口         3.通过匿名内部类方式创建Thread与实现

    2024年02月03日
    浏览(35)
  • 初识网络 --- 浅了解一些基础概念

    在每台计算机独立的情况下:假设现在有三台计算机,每台计算机各持有一个业务。那么现在有个程序员处理业务时,如果想要处理业务1就要操作计算机1,处理业务2就要操作计算机2,这样的效率明显不高 那么如果能将三台计算机都连接到一台服务器中,那么三台计算机就

    2024年02月11日
    浏览(39)
  • 初步了解SpringCloud微服务架构

    ✅作者简介:大家好,我是Cisyam,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Cisyam-Shark的博客 💞当前专栏: 微服务探索之旅 ✨特色专栏: MySQL学习 🥭本文内容:初步了解SpringCloud微服务架构 🖥️个人小站 :个人博客,欢迎大家访问 📚个人

    2024年02月08日
    浏览(44)
  • 【云原生】初识Docker,安装以及了解操作命令

    背景:以前开发、测试、生产为不同的环境,痛点是发现开发测试以后没问题,但是在生产环境无法运行。给测试、开发、运维人员造成了大量的工作。最终结果是发版更新速度也跟不上,效率低 我认为使用容器的核心原因:降本增效 容器可以屏蔽底层操作系统的差异性,

    2024年01月24日
    浏览(52)
  • 【Elasticsearch】初识elasticsearch

    目录 初识elasticsearch 1.1.了解ES 1.1.1.elasticsearch的作用 1.1.2.ELK技术栈 1.1.3.elasticsearch和lucene 1.1.4.为什么不是其他搜索技术? 1.1.5.总结 1.2.倒排索引 1.2.1.正向索引 1.2.2.倒排索引 1.2.3.正向和倒排 1.3.es的一些概念 1.3.1.文档和字段 1.3.2.索引和映射 1.3.3.mysql与elasticsearch 1.1.1.elasticsea

    2024年02月13日
    浏览(36)
  • 【elasticsearch系】1.初识玩转elasticSearch

    首先给大家介绍下我使用的版本是7.17.3这个版本,关于之前6.x的版本还是有些区别的。 elasticSearch Elasticsearch 是一个分布式文档存储。Elasticsearch 不是将信息存储为列式数据行,而是存储已序列化为 JSON 文档的复杂数据结构。存储文档时,会在1 秒内近乎实时地为其建立索引并

    2024年02月15日
    浏览(34)
  • SpringBoot 和 SpringCloud 有什么区别,一起来学习了解他们

    Spring Boot和Spring Cloud是两个非常流行的Java开发框架,它们都是由Spring Framework开发的,但是它们的定位和功能有所不同。本文将介绍Spring Boot和Spring Cloud的区别。 Spring Boot是一个轻量级的应用程序框架,它的目的是使Spring应用程序的开发变得更加快速和容易。Spring Boot通过自动

    2024年02月14日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包