Elasticsearch的索引库和文档操作、RestClient的索引库和文档操作

news2024/11/19 3:27:12

一、Elasticsearch

Linux系统通过Docker安装Elasticsearch、部署kibana

1.Elasticsearch

Elasticsearch 是位于 Elastic Stack 核心的分布式搜索和分析引擎。Logstash 和 Beats
有助于收集、聚合和丰富您的数据并将其存储在 Elasticsearch 中。Kibana
使您能够以交互方式探索、可视化和分享对数据的见解,并管理和监控堆栈。

简单的说:elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容

1.1Elasticsearch的一些概念

elasticsearch中有很多独有的概念,与mysql中略有差别,但也有相似之处。

1.1.1.文档和字段

elasticsearch是面向文档(Document)存储的,可以是数据库中的一条商品数据,一个订单信息。
在这里插入图片描述

文档数据会被序列化为json格式后存储在elasticsearch中:而Json文档中往往包含很多的字段(Field),类似于数据库中的列。

1.1.2.索引和映射

索引(Index),就是相同类型的文档的集合。

例如:

  • 所有用户文档,就可以组织在一起,称为用户的索引;
  • 所有商品的文档,可以组织在一起,称为商品的索引;
  • 所有订单的文档,可以组织在一起,称为订单的索引;
    在这里插入图片描述

因此,我们可以把索引当做是数据库中的表。

数据库的表会有约束信息,用来定义表的结构、字段的名称、类型等信息。因此,索引库中就有映射(mapping),是索引中文档的字段约束信息,类似表的结构约束。

1.1.3.mysql与elasticsearch

我们统一的把mysql与elasticsearch的概念做一下对比:

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

是不是说,我们学习了elasticsearch就不再需要mysql了呢?

并不是如此,两者各自有自己的擅长支出:

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

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

因此在企业中,往往是两者结合使用:

  • 对安全性要求较高的写操作,使用mysql实现
  • 对查询性能要求较高的搜索需求,使用elasticsearch实现
  • 两者再基于某种方式,实现数据的同步,保证一致性

2.Elasticsearch的索引库操作

2.1.mapping映射属性

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

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

例如下面的json文档:

{
    "age": 21,
    "weight": 52.1,
    "isMarried": false,
    "info": "黑马程序员Java讲师",
    "email": "zy@itcast.cn",
    "score": [99.1, 99.5, 98.9],
    "name": {
        "firstName": "云",
        "lastName": "赵"
    }
}

对应的每个字段映射(mapping):

  • age:类型为 integer;参与搜索,因此需要index为true;无需分词器
  • weight:类型为float;参与搜索,因此需要index为true;无需分词器
  • isMarried:类型为boolean;参与搜索,因此需要index为true;无需分词器
  • info:类型为字符串,需要分词,因此是text;参与搜索,因此需要index为true;分词器可以用ik_smart
  • email:类型为字符串,但是不需要分词,因此是keyword;不参与搜索,因此需要index为false;无需分词器
  • score:虽然是数组,但是我们只看元素的类型,类型为float;参与搜索,因此需要index为true;无需分词器
  • name:类型为object,需要定义多个子属性
    • name.firstName;类型为字符串,但是不需要分词,因此是keyword;参与搜索,因此需要index为true;无需分词器
    • name.lastName;类型为字符串,但是不需要分词,因此是keyword;参与搜索,因此需要index为true;无需分词器

2.2.索引库的CRUD

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

这里我们统一使用Kibana编写DSL的方式来演示。
就是如下图这里:
在这里插入图片描述

2.2.1.创建索引库和映射

基本语法:

  • 请求方式:PUT
  • 请求路径:/索引库名,可以自定义
  • 请求参数:mapping映射

格式:

PUT /索引库名称
{
  "mappings": {
    "properties": {
      "字段名":{
        "type": "text",
        "analyzer": "ik_smart"
      },
      "字段名2":{
        "type": "keyword",
        "index": "false"
      },
      "字段名3":{
        "type":"object",
        "properties": {
          "子字段": {
            "type": "keyword"
          }
        }
      },
     // ...略
    }
  }
}

示例:

#创建索引库
PUT /laohuang
{
  "mappings": {
    "properties": {
        "info":{
            "type": "text",
            "analyzer": "ik_smart"
        },
        "email":{
          "type": "keyword",
          "index": false
        },
        "name":{
          "type": "object", 
          "properties": {
              "firstName":{
                  "type":"keyword"
              },
              "lastName":{
                   "type":"keyword"
              }
          }
        }
    }
  }
}

结果截图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ceQMNRT4-1683454694410)(assets/1646668293597.png)]

2.2.2.查询索引库

基本语法

  • 请求方式:GET

  • 请求路径:/索引库名

  • 请求参数:无

格式

GET /索引库名

示例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MMqEiQ4m-1683454694410)(assets/image-20210720211019329.png)]

2.2.3.修改索引库

倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引,这简直是灾难。因此索引库一旦创建,无法修改mapping

虽然无法修改mapping中已有的字段,但是却允许添加新的字段到mapping中,因为不会对倒排索引产生影响。

语法说明

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

示例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UJoWFaAy-1683454694411)(assets/image-20210720212357390.png)]

2.2.4.删除索引库

语法:

  • 请求方式:DELETE

  • 请求路径:/索引库名

  • 请求参数:无

格式:

DELETE /索引库名

在kibana中测试:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xbDFaQwe-1683454694412)(assets/image-20210720212123420.png)]

3.文档操作

文档操作有哪些?

  • 创建文档:POST /{索引库名}/_doc/文档id { json文档 }
  • 查询文档:GET /{索引库名}/_doc/文档id
  • 删除文档:DELETE /{索引库名}/_doc/文档id
  • 修改文档:
    • 全量修改:PUT /{索引库名}/_doc/文档id { json文档 }
    • 增量修改:POST /{索引库名}/_update/文档id { “doc”: {字段}}

3.1.新增文档

语法:

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

示例:

POST /laohuang/_doc/1
{
  "email": "123@123.com",
  "info": "老黄秃头发",
  "name": {
    "firstName": "老",
    "lastName": "黄"
  }
}

响应:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wK05OFkk-1683460258082)(assets/image-20210720212933362.png)]

3.2.查询文档

根据rest风格,新增是post,查询应该是get,不过查询一般都需要条件,这里我们把文档id带上。

语法:

GET /{索引库名称}/_doc/{id}

通过kibana查看数据:

GET /laohuang/_doc/1

查看结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HWC2IQXW-1683460258083)(assets/image-20210720213345003.png)]

3.3.删除文档

删除使用DELETE请求,同样,需要根据id进行删除:

语法:

DELETE /{索引库名}/_doc/id值

示例:

# 根据id删除数据
DELETE /laohuang/_doc/1

结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GUNJpETc-1683460258084)(assets/image-20210720213634918.png)]

3.4.修改文档

修改有两种方式:

  • 全量修改:直接覆盖原来的文档
  • 增量修改:修改文档中的部分字段

3.4.1.全量修改

全量修改是覆盖原来的文档,其本质是:

  • 根据指定的id删除文档
  • 新增一个相同id的文档

注意:如果根据id删除时,id不存在,第二步的新增也会执行,也就从修改变成了新增操作了。

语法:

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

示例:

PUT /laohuang/_doc/1
{
  "email":"123@321.com",
  "info":"老黄头发少",
  "name":{
    "firstName": "耄",
    "lastName":"黄"
  }
}

3.4.2.增量修改

增量修改是只修改指定id匹配的文档中的部分字段。

语法:

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

示例:

PUT /laohuang/_doc/1
{
  "doc":{
    "info":"老黄没头发"
  }
}

在这里插入图片描述

3.5 查询全部文档

查看当前索引库中所有的文档,查询用GET请求

语法:

GET /{索引库名称}/_search

示例:

GET /laohuang/_search

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TCeppe9O-1683460258084)(assets/1646670314636.png)]

4.RestClient 操作索引库

JavaRestClient操作elasticsearch的流程基本类似。核心是client.indices()方法来获取索引库的操作对象。 索引库操作的基本步骤:

  • 创建索引库
  • 初始化RestHighLevelClient
  • 准备DSL( Create时需要,其它是无参)
  • 创建XxxIndexRequest。XXX是Create、Get、Delete
  • 发送请求。调用RestHighLevelClient#indices().xxx()方法,xxx是create、exists、delete

4.1.创建索引库

引入依赖

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

因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本:

<properties>
    <java.version>1.8</java.version>
    <elasticsearch.version>7.12.1</elasticsearch.version>
</properties>

导入案例数据库结构

CREATE TABLE `tb_hotel` (
  `id` bigint(20) NOT NULL COMMENT '酒店id',
  `name` varchar(255) NOT NULL COMMENT '酒店名称;例:7天酒店',
  `address` varchar(255) NOT NULL COMMENT '酒店地址;例:航头路',
  `price` int(10) NOT NULL COMMENT '酒店价格;例:329',
  `score` int(2) NOT NULL COMMENT '酒店评分;例:45,就是4.5分',
  `brand` varchar(32) NOT NULL COMMENT '酒店品牌;例:如家',
  `city` varchar(32) NOT NULL COMMENT '所在城市;例:上海',
  `star_name` varchar(16) DEFAULT NULL COMMENT '酒店星级,从低到高分别是:1星到5星,1钻到5钻',
  `business` varchar(255) DEFAULT NULL COMMENT '商圈;例:虹桥',
  `latitude` varchar(32) NOT NULL COMMENT '纬度;例:31.2497',
  `longitude` varchar(32) NOT NULL COMMENT '经度;例:120.3925',
  `pic` varchar(255) DEFAULT NULL COMMENT '酒店图片;例:/img/1.jpg',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

mapping映射分析生成索引库结构

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",
        "copy_to": "all"
      },
      "starName":{
        "type": "keyword"
      },
      "business":{
        "type": "keyword"
      },
      "location":{
        "type": "geo_point"
      },
      "pic":{
        "type": "keyword",
        "index": false
      },
      "all":{
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

几个特殊字段说明:

  • location:地理坐标,里面包含精度、纬度
  • all:一个组合字段,其目的是将多字段的值 利用copy_to合并,提供给用户搜索

4.2.初始化RestHighLevelClient

@Configuration
public class RestHighLevelConfig {
    @Bean
    RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
                //地址是虚拟机ip地址:9200
                RestClient.builder(HttpHost.create("http://192.168.80.128:9200"))
        );
        return restHighLevelClient;
    }
}

4.3准备DSL

public class HotelConstants {
    public static final String MAPPING_TEMPLATE = "{\n" +
            "  \"mappings\": {\n" +
            "    \"properties\": {\n" +
            "      \"id\": {\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"name\":{\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_max_word\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"address\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"price\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"score\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"brand\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"city\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"copy_to\": \"all\"\n" +
            "      },\n" +
            "      \"starName\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"business\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"location\":{\n" +
            "        \"type\": \"geo_point\"\n" +
            "      },\n" +
            "      \"pic\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"all\":{\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_max_word\"\n" +
            "      }\n" +
            "    }\n" +
            "  }\n" +
            "}";
}

4.3.创建XxxIndexRequest。XXX是Create、Get、Delete,并发送请求

@SpringBootTest
class HotelDemoApplicationTests {

    @Autowired
    private RestHighLevelClient client;

    @Test
    void createIndex() throws IOException {
        CreateIndexRequest request = new CreateIndexRequest("hotel");
        request.source(HotelConstants.MAPPING_TEMPLATE, XContentType.JSON);
        client.indices().create(request, RequestOptions.DEFAULT);
    }

    @Test
    void deleteIndex() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest("hotel");
        client.indices().delete(request,RequestOptions.DEFAULT);
    }

    @Test
    void getIndex() throws IOException{
        GetIndexRequest request = new GetIndexRequest("hotel");
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.err.println(exists==true?"已经存在":"索引库没存在");
    }
}

5.RestClient操作文档

5.1.新增文档

我们要将数据库的酒店数据查询出来,写入elasticsearch中。

5.1.1.索引库实体类

数据库查询后的结果是一个Hotel类型的对象。结构如下:

@Data
@TableName("tb_hotel")
public class Hotel {
    @TableId(type = IdType.INPUT)
    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 longitude;
    private String latitude;
    private String pic;
}

与我们的索引库结构存在差异:

  • longitude和latitude需要合并为location

因此,我们需要定义一个新的类型,与索引库结构吻合:

package cn.itcast.hotel.pojo;

import lombok.Data;
import lombok.NoArgsConstructor;

@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();
    }
}

5.1.2.语法说明

新增文档的DSL语句如下:

POST /{索引库名}/_doc/1
{
    "name": "Jack",
    "age": 21
}

对应的java代码如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ufABAjc4-1683528264146)(assets/image-20210720230027240.png)]

可以看到与创建索引库类似,同样是三步走:

  • 1)创建Request对象
  • 2)准备请求参数,也就是DSL中的JSON文档
  • 3)发送请求

变化的地方在于,这里直接使用client.xxx()的API,不再需要client.indices()了。

5.1.3.完整代码

我们导入酒店数据,基本流程一致,但是需要考虑几点变化:

  • 酒店数据来自于数据库,我们需要先查询出来,得到hotel对象
  • hotel对象需要转为HotelDoc对象
  • HotelDoc需要序列化为json格式

因此,代码整体步骤如下:

  • 1)根据id查询酒店数据Hotel
  • 2)将Hotel封装为HotelDoc
  • 3)将HotelDoc序列化为JSON
  • 4)创建IndexRequest,指定索引库名和id
  • 5)准备请求参数,也就是JSON文档
  • 6)发送请求

在hotel-demo的HotelDocumentTest测试类中,编写单元测试:

@Test
    @Test
    void createDoc() throws IOException{
        //根据id查询酒店数据
        Hotel hotel = hotelService.getById(61083L);
        //转换为文档模型
        HotelDoc hotelDoc = new HotelDoc(hotel);
        //将文档模型转为JSON
        String hotelDocJson = JSONObject.toJSONString(hotelDoc);
        //准备request对象
        IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
        //将json文档放入请求中
        request.source(hotelDocJson,XContentType.JSON);
        //发送请求
        client.index(request,RequestOptions.DEFAULT);
    }

发送完、在kibana的doc检查

在这里插入图片描述

5.2.查询文档

5.2.1.语法说明

查询的DSL语句如下:

GET /hotel/_doc/{id}

非常简单,因此代码大概分两步:

  • 准备Request对象
  • 发送请求

不过查询的目的是得到结果,解析为HotelDoc,因此难点是结果的解析。完整代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6TllJAAa-1683528264148)(assets/image-20210720230811674.png)]

可以看到,结果是一个JSON,其中文档放在一个_source属性中,因此解析就是拿到_source,反序列化为Java对象即可。

与之前类似,也是三步走:

  • 1)准备Request对象。这次是查询,所以是GetRequest
  • 2)发送请求,得到结果。因为是查询,这里调用client.get()方法
  • 3)解析结果,就是对JSON做反序列化

5.2.2.完整代码

在hotel-demo的HotelDocumentTest测试类中,编写单元测试:

    @Test
    void getDoc() throws  IOException{
        //准备request请求
        GetRequest request = new GetRequest("hotel","61083");
        //发送请求
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        //解析response
        String json = response.getSourceAsString();
        HotelDoc hotelDoc = JSONObject.parseObject(json, HotelDoc.class);
        System.out.println(hotelDoc);
    }

运行结果
在这里插入图片描述

5.3.删除文档

删除的DSL为是这样的:

DELETE /hotel/_doc/{id}

与查询相比,仅仅是请求方式从DELETE变成GET,可以想象Java代码应该依然是三步走:

  • 1)准备Request对象,因为是删除,这次是DeleteRequest对象。要指定索引库名和id
  • 2)准备参数,无参
  • 3)发送请求。因为是删除,所以是client.delete()方法

在hotel-demo的HotelDocumentTest测试类中,编写单元测试:

    @Test
    void deleteDoc() throws IOException{
        //获取请求
        DeleteRequest deleteRequest = new DeleteRequest("hotel","61083");
        //发送请求
        client.delete(deleteRequest,RequestOptions.DEFAULT);
    }

测试运行结果:
在这里插入图片描述

5.4.修改文档

5.4.1.语法说明

修改我们讲过两种方式:

  • 全量修改:本质是先根据id删除,再新增
  • 增量修改:修改文档中的指定字段值

这里不再赘述,我们主要关注增量修改。

代码示例如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uzANn9GR-1683528264149)(assets/image-20210720231040875.png)]

与之前类似,也是三步走:

  • 1)准备Request对象。这次是修改,所以是UpdateRequest
  • 2)准备参数。也就是JSON文档,里面包含要修改的字段
  • 3)更新文档。这里调用client.update()方法

5.4.2.完整代码

在hotel-demo的HotelDocumentTest测试类中,编写单元测试:

    void OneUpdateDoc() throws IOException{
        //准备request对象
        UpdateRequest request = new UpdateRequest("hotel","61083");
        //准备修改的参数
        request.doc(
                "starName","老黄钻"
        );
        //发送请求
        client.update(request,RequestOptions.DEFAULT);
    }

测试结果:
在这里插入图片描述

5.5.批量导入文档

案例需求:利用BulkRequest批量将数据库数据导入到索引库中。

步骤如下:

  • 利用mybatis-plus查询酒店数据

  • 将查询到的酒店数据(Hotel)转换为文档类型数据(HotelDoc)

  • 利用JavaRestClient中的BulkRequest批处理,实现批量新增文档

5.5.1.语法说明

批量处理BulkRequest,其本质就是将多个普通的CRUD请求组合在一起发送。

其中提供了一个add方法,用来添加其他请求:

能添加的请求包括:

  • IndexRequest,也就是新增
  • UpdateRequest,也就是修改
  • DeleteRequest,也就是删除

因此Bulk中添加了多个IndexRequest,就是批量新增功能了。

其实还是三步走:

  • 1)创建Request对象。这里是BulkRequest
  • 2)准备参数。批处理的参数,就是其它Request对象,这里就是多个IndexRequest
  • 3)发起请求。这里是批处理,调用的方法为client.bulk()方法

我们在导入酒店数据时,将上述代码改造成for循环处理即可。

5.5.2.完整代码

在hotel-demo的HotelDocumentTest测试类中,编写单元测试:

    @Test
    void bulkDoc() throws IOException{
        List<Hotel> allHotel = hotelService.list();
        //创建BulkRequest
        BulkRequest request = new BulkRequest();
        for (Hotel hotel : allHotel) {
            //将hotel转成hoteldoc
            HotelDoc hotelDoc = new HotelDoc(hotel);
            //创建新增文档的新增对象
            request.add(new IndexRequest("hotel").id(hotel.getId().toString())
            .source(JSONObject.toJSONString(hotelDoc),XContentType.JSON));
        }
        //发送请求
        client.bulk(request,RequestOptions.DEFAULT);
    }

测试结果:
在这里插入图片描述

5.6总结

请求发送
删除索引库DeleteIndexRequestclient.indices().delete(…)
创建索引库CreateIndexRequestclient.indices().create(…)
判断索引库是否存在GetIndexRequestclient.indices().exists(…)
步骤
删除索引库1)创建Request对象。 2)添加请求参数,其实就是DSL的JSON参数部分。 3)发送请求,
创建索引库1)创建Request对象。 2)准备参数。这里是无参 3)发送请求。改用delete方法
判断索引库是否存在1)创建Request对象。2)准备参数。这里是无参 3)发送请求。改用exists方法
请求发送
新增文档数据IndexRequest(…)client.index(…)
查询文档数据GetRequest(…)client.get(…)
删除文档数据DeleteRequest(…)client.delete(…)
修改文档数据(全量)DeleteRequest(…) AND IndexRequest(…)client.delete(…) AND client.index(…)
修改文档数据(增量)UpdateRequest(…)client.update(…)
批量新增文档数据BulkRequest(…)client.bulk(…)
步骤
新增文档数据1)创建Request对象 2)准备请求参数,也就是DSL中的JSON文档 3)发送请求
查询文档数据1)准备Request对象 2)发送请求
删除文档数据1)准备Request对象,因为是删除,这次是DeleteRequest对象。要指定索引库名和id 2)准备参数,无参 3)发送请求。因为是删除,所以是client.delete()方法
修改文档数据(全量)1)先根据id删除文档数据,2)新增文档数据
修改文档数据(增量)1)准备Request对象。这次是修改,所以是UpdateRequest 2)准备参数。也就是JSON文档,里面包含要修改的字段 3)更新文档。这里调用client.update()方法
批量新增文档数据1)创建Request对象。这里是BulkRequest 2)准备参数。批处理的参数,就是其它Request对象,这里就是多个IndexRequest 3)发起请求。这里是批处理,调用的方法为client.bulk()方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/502755.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

梅果提取物激增2782%?因字成分崛起|3月功效成分TOP100

全文速览 全文字数&#xff1a;6015字 阅读时长&#xff1a;8-12分钟 1.目前已有11款新原料成分进入监测期&#xff0c;三月新原料备案占比达27.1%。 2.天赐高新成为仅次于美国路博润的全球第二大卡波姆供应商&#xff0c;市占率将近两成。 3.氨基酸洗面奶凭多重功效替代皂…

Flink Dashboard的数据监控功能

一、数据反压 1.1 数据反压是啥 数据反压是在实时数据处理中&#xff0c;数据处理流的某个节点上游产生数据的速度大于该节点处理数据速度&#xff0c;导致数据堆积&#xff0c;从该节点向上游传递&#xff0c;一直到数据源&#xff0c;并降低数据源的摄入速度。导致数据反压…

如何远程内网电脑

要远程访问内联网计算机&#xff0c;您需要遵循以下一般步骤&#xff1a; 连接到与目标计算机相同的局域网 (LAN)。 这可能涉及到现场或使用 VPN 远程连接到 LAN。 获取目标计算机的 IP 地址或网络名称。 确保在目标计算机上启用了远程桌面访问。 使用远程桌面软件与目标计…

ASP.NET Core 8 中身份验证的改进

ASP.NET Core 团队正在改进 .NET 8 中的身份验证、授权和身份管理(统称为“身份验证”)。新的 APIs 将使自定义用户登录和身份管理体验变得更加容易。新的端点将在没有外部依赖的单页应用程序(SPA)中启用基于令牌的身份验证和授权。我们还将改进我们的指引和文档&#xff0c;使…

数据结构绪论

数据结构绪论 1.数据结构 数据结构 数据结构是相互之间存在一种或多种特定关系的数据元素的集合。数据结构是一门研究非数值计算的程序设计问题中的操作对象&#xff0c;以及他们之间的关系和操作等相关问题的学科。 数据 数据:是描述客观事物的符号&#xff0c;是计算机中可以…

Dtop环球嘉年华全球Web3.0分布式私域电商生态发展峰会圆满举办

5月7日,Dtop环球嘉年华全球Web3.0分布式跨境私域电商生态发展峰会暨战略合作备忘录签署仪式在马来西亚首都吉隆坡隆重举办。此次峰会汇集了Dtop环球嘉年华韩国、新加坡、澳洲、泰国、印尼等国家的社区联合发起人,环球自治商学院地区代表及来自Dtop环球嘉年华不同国家的粉丝用户…

nas各种共享访问协议的使用(smb,nfs,ftp,ftps,sftp,afp,webdav)

使用群晖、UNRAID、FREENAS等NAS系统的小伙伴肯定会有传输文件的需求&#xff0c;无论是在本地局域网还是远端设备&#xff0c;这种情况下当然可以使用群晖的WEB管理界面中File Station&#xff0c;但是这种方式便捷性不够&#xff0c;于是nas与本地设备文件的传输最好的方式是…

lua | table表的使用操作

目录 lua table表 表的构造 Table的使用 table.concat() table.insert()与table.remove() table.sort() table.maxn() 本文章为笔者学习分享 学习网站&#xff1a;Lua 基本语法 | 菜鸟教程 lua table表 table&#xff1a;是lua的一种数据结构&#xff0c;用来帮助我们…

为什么Windows 10电脑运行缓慢?如何解决?

​虽然电脑是大家生活中的常用工具&#xff0c;但它经常会出现一些烦人的小问题&#xff0c;比如Windows 10系统在长时间使用后运行会变的缓慢。这时你必须等待一会才能打开/关闭电脑、打开和访问文件夹或软件&#xff0c;那要如何优化Windows 10电脑来解决运行缓慢的问题呢&am…

如何在 Espressif-IDE 中使用 Wokwi 模拟器

乐鑫近期已发布 Espressif-IDE v2.9.0&#xff0c;您可直接在此版本的 IDE 中使用 Wokwi 模拟器。 什么是 Wokwi 模拟器&#xff1f; Wokwi 是一款在线电子模拟器&#xff0c;支持模拟各种开发板、元器件和传感器&#xff0c;例如乐鑫产品 ESP32。 Wokwi 提供基于浏览器的界面…

C++学习day--08 数组和字符串

1、什么是数组 数组&#xff0c;就是多个元素的有序“组合”。 C 和 C语言中的数组&#xff1a; 1 &#xff09;由多个大小相同的小柜子组成 > 相同大小的内存块组成&#xff0c;即相同类型的数据 2 &#xff09;这些小柜子&#xff0c;有自己对应的编号 > 编号从 …

软考中级工程师笔记(持续更新)

进制 正负0 -0原000110010000 1000反000111100000 1111补000111110000 0000 取值范围 原 -(2n-1)-1~(2n-1)-1 数量 [(2n-1)-1]-[-(2n-1)-1] 1(1代表0)(2*2n-1)-1**2n-1** 反 -(2n-1)-1~(2n-1)-1 数量 [(2n-1)-1]-[-(2n-1)-1] 1(1代表0)(2*2n-1)-1**2n-1** 补 -(2n-1)~(2n-…

算法设计 || 实验一 用分治法实现元素的归并与检索 (头歌详解+本题分析笔记)

目录 &#xff08;一&#xff09;递归与分治是个啥&#xff1f; 1.递归&#xff08;归并排序&#xff09; 2.分治&#xff08;二分检索算法&#xff09; &#xff08;二&#xff09;头歌代码怎么写&#xff1f; &#xff08;三&#xff09;代码部分详解&#xff1a; &…

Android内嵌Unity (Activity)

Unity2019.4.4 AndropidStudio4.2.1 参考文档&#xff1a; Android内嵌Unity并实现互相跳转的实例代码_Android_脚本之家 Android Fragment中加载,嵌套Unity视图_unity 导入并作为fragment_周灬浩的博客-CSDN博客 本文只实现了Activity整个切换过去&#xff0c;而Fragment…

WSL2 ubuntu ip 自动同步 、静态ip(解决wsl2 ip 每次开机ip会变化的问题)

​ 利用python脚本解决wsl2 ip不固定的问题 环境信息 ​ wsl2 中linux版本&#xff1a;ubuntu ​ windows版本&#xff1a; win10/win11 问题描述 最近装了wsl2&#xff0c;使用vscode远程连接wsl2时遇到了如下问题&#xff1a; 1、wsl2的ip无法固定 2、wsl2的ssh服务不能…

vue项目使用element-ui

最近新建一个vue项目&#xff0c;配置了element-ui&#xff0c;较之前使用时发生了些许变化&#xff0c;对新的配置方式进行记录 node版本 v14.21.3 npm版本 v6.14.18 vue版本 v2.6.14 element-ui版本 v2.15.13 创建项目vue项目&#xff0c;使用…

设计原则之【迪米特法则】

文章目录 一、什么是迪米特法则1、理解迪米特法则2、如何理解“高内聚、松耦合”&#xff1f; 二、实例1、实例12、实例2 一、什么是迪米特法则 迪米特原则&#xff08;Law of Demeter LoD&#xff09;是指一个对象应该对其他对象保持最少的了解&#xff0c;又叫最少知道原则&…

Navicat自动提交的开和关

使用Navicat时&#xff0c;若是自动提交是打开状态&#xff0c;就相当于是自动执行了commit操作&#xff0c;就无法进行回滚操作。 一.相关指令 1.查询Navicat的自动提交开关状态&#xff1a; -- 查询自动提交 ON:是自动提交&#xff0c;即commit ;OFF:不是自动提交&#xf…

Java-注解

文章目录 前言一、概述二、元注解TargetRetentionDocumentedInherited 三、自定义注解四、常用内置注解OverrideDeprecatedSuppressWarnings 前言 注解用于修饰包、类、方法、属性、构造器、局部变量等数据信息&#xff0c;它可以用于创建文档&#xff0c;跟踪代码的依赖性&am…

怎么在VMware ESXi添加NAS存储?

案例&#xff1a;需要将NAS添加到VMware ESXi “我的本地空间不是很多&#xff0c;虚拟机占了我很多空间&#xff0c;但是我有一个NAS&#xff0c;所以我想问一下有没有办法可以让VMware ESXi添加NAS存储来扩展空间&#xff1f;” 网络附加存储&#xff08;NAS&#xff09;设…