微服务day08

news2024/12/26 21:21:39

Elasticsearch

 

需要安装elasticsearch和Kibana,应为Kibana中有一套控制台可以方便的进行操作。

安装elasticsearch

使用docker命令安装:

docker run -d \ 
  --name es \
  -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \  //设置他的运行内存空间,不要低于512否则出问题
  -e "discovery.type=single-node" \ //设置安装模式,当前为单点模式,而非集群模式。
  -v es-data:/usr/share/elasticsearch/data \
  -v es-plugins:/usr/share/elasticsearch/plugins \
  --privileged \
  --network hm-net \
  -p 9200:9200 \
  -p 9300:9300 \  //集群通信的端口。
  elasticsearch:7.12.1

安装Kibana

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

通过kibana向es发送Http请求。

倒排索引

小结:

IK分词器

安装

在线安装:

docker exec -it es ./bin/elasticsearch-plugin  install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.1/elasticsearch-analysis-ik-7.12.1.zip

重启:

docker restart es

线下安装:

首先,查看之前安装的Elasticsearch容器的plugins数据卷目录:

docker volume inspect es-plugins

结果如下:

[
    {
        "CreatedAt": "2024-11-06T10:06:34+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/es-plugins/_data",
        "Name": "es-plugins",
        "Options": null,
        "Scope": "local"
    }
]

可以看到elasticsearch的插件挂载到了/var/lib/docker/volumes/es-plugins/_data这个目录。我们需要把IK分词器上传至这个目录。

找到课前资料提供的ik分词器插件,课前资料提供了7.12.1版本的ik分词器压缩文件,你需要对其解压:

然后上传至虚拟机的/var/lib/docker/volumes/es-plugins/_data这个目录

重启es容器:

docker restart es

IK分词器包含两种模式:

  • ik_smart:智能语义切分

  • ik_max_word:最细粒度切分

POST /_analyze
{
  "analyzer": "ik_smart",
  "text": "黑马程序员学习java太棒了"
}

结果:

{
  "tokens" : [
    {
      "token" : "黑马",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "程序员",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "学习",
      "start_offset" : 5,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "java",
      "start_offset" : 7,
      "end_offset" : 11,
      "type" : "ENGLISH",
      "position" : 3
    },
    {
      "token" : "太棒了",
      "start_offset" : 11,
      "end_offset" : 14,
      "type" : "CN_WORD",
      "position" : 4
    }
  ]
}

由于互联网词汇不断增多,需要拓展词汇库。

所以要想正确分词,IK分词器的词库也需要不断的更新,IK分词器提供了扩展词汇的功能。

1)打开IK分词器config目录:

注意,如果采用在线安装的通过,默认是没有config目录的,需要把课前资料提供的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>
</properties>

在IK分词器的config目录新建一个 ext.dic,可以参考config目录下复制一个配置文件进行修改:

传智播客
泰裤辣

重启elasticsearch

docker restart es

再次测试,可以发现传智播客泰裤辣都正确分词了:

{
  "tokens" : [
    {
      "token" : "传智播客",
      "start_offset" : 0,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "开设",
      "start_offset" : 4,
      "end_offset" : 6,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "大学",
      "start_offset" : 6,
      "end_offset" : 8,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "真的",
      "start_offset" : 9,
      "end_offset" : 11,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "泰裤辣",
      "start_offset" : 11,
      "end_offset" : 14,
      "type" : "CN_WORD",
      "position" : 4
    }
  ]
}

总结

分词器的作用是什么?

  • 创建倒排索引时,对文档分词

  • 用户搜索时,对输入的内容分词

IK分词器有几种模式?

  • ik_smart:智能切分,粗粒度

  • ik_max_word:最细切分,细粒度

IK分词器如何拓展词条?如何停用词条?

  • 利用config目录的IkAnalyzer.cfg.xml文件添加拓展词典和停用词典

  • 在词典中添加拓展词条或者停用词条

基础概念

索引库操作

Mapping映射属性

索引库操作

Restful规范

索引库操作

创建索引库:

基本语法

  • 请求方式:PUT

  • 请求路径:/索引库名,可以自定义

  • 请求参数:mapping映射

格式:

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

 实例代码

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

返回结果:

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "hmall"
}
查询索引库

基本语法

  • 请求方式:GET

  • 请求路径:/索引库名

  • 请求参数:无

格式

GET /索引库名

实例代码

GET /hmall

查询结果:

{
  "hmall" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "email" : {
          "type" : "keyword",
          "index" : false
        },
        "info" : {
          "type" : "text",
          "analyzer" : "ik_smart"
        },
        "name" : {
          "properties" : {
            "firstName" : {
              "type" : "keyword"
            },
            "lastName" : {
              "type" : "keyword"
            }
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "routing" : {
          "allocation" : {
            "include" : {
              "_tier_preference" : "data_content"
            }
          }
        },
        "number_of_shards" : "1",
        "provided_name" : "hmall",
        "creation_date" : "1731489076840",
        "number_of_replicas" : "1",
        "uuid" : "KJqNTGY9RhiqFHkliRdGcw",
        "version" : {
          "created" : "7120199"
        }
      }
    }
  }
}
修改索引库

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

虽然无法修改mapping中已有的字段,但是却允许添加新的字段到mapping中,因为不会对倒排索引产生影响。因此修改索引库能做的就是向索引库中添加新字段,或者更新索引库的基础属性。

语法说明:

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

添加字段:

PUT /hmall/_mapping
{
  "properties": {
    "age":{
      "type": "integer"
    }
  }
}

返回结果:

{
  "acknowledged" : true
}
删除索引库

语法:

  • 请求方式:DELETE

  • 请求路径:/索引库名

  • 请求参数:无

语法格式

DELETE /索引库名

删除库

DELETE /hmall

执行结果

{
  "acknowledged" : true
}
索引库操作总结:

索引库操作有哪些?

  • 创建索引库:PUT /索引库名

  • 查询索引库:GET /索引库名

  • 删除索引库:DELETE /索引库名

  • 修改索引库,添加字段:PUT /索引库名/_mapping

可以看到,对索引库的操作基本遵循的Restful的风格,因此API接口非常统一,方便记忆。

文档操作

新增文档

语法规范

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

实例代码

POST /hmall/_doc/1
{
    "info": "黑马程序员Java讲师",
    "email": "zy@itcast.cn",
    "name": {
        "firstName": "云",
        "lastName": "赵"
    }
}

运行结果

{
  "_index" : "hmall",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 8,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 8,
  "_primary_term" : 1
}
查询文档

语法规范

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

实例代码

GET /hmall/_doc/1

运行结果

{
  "_index" : "hmall",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 8,
  "_seq_no" : 8,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "info" : "黑马程序员Java讲师",
    "email" : "zy@itcast.cn",
    "name" : {
      "firstName" : "云",
      "lastName" : "赵"
    }
  }
}
删除文档

语法规范

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

实例代码

DELETE /hmall/_doc/1

运行结果

{
  "_index" : "hmall",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 9,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 9,
  "_primary_term" : 1
}
修改文档
全量修改

语法规范

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

实例代码

#全量修改
PUT /hmall/_doc/1
{
  "info": "黑马程序员Python讲师",
    "email": "ls@itcast.cn",
    "name": {
        "firstName": "四",
        "lastName": "李"
    }
}

运行结果

第一次运行,由于前面已经删除了该文档所以 执行类型为 created.

{
  "_index" : "hmall",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 10,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 10,
  "_primary_term" : 1
}

 第二次运行,为修改返回的类型为 updated。

{
  "_index" : "hmall",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 11,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 11,
  "_primary_term" : 1
}
部分修改

语法规范

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

实例代码

#局部修改
POST /hmall/_update/1
{
  "doc": {
    "email":"ZhaoYuen@itcast.com"
  }
}

运行结果

{
  "_index" : "hmall",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 12,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 12,
  "_primary_term" : 1
}

当前文档的数据:

{
  "_index" : "hmall",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 12,
  "_seq_no" : 12,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "info" : "黑马程序员Python讲师",
    "email" : "ZhaoYuen@itcast.com",
    "name" : {
      "firstName" : "四",
      "lastName" : "李"
    }
  }
}
文档基础操作小结

文档批量处理

  • index代表新增操作

    • _index:指定索引库名

    • _id指定要操作的文档id

    • { "field1" : "value1" }:则是要新增的文档内容

  • delete代表删除操作

    • _index:指定索引库名

    • _id指定要操作的文档id

  • update代表更新操作

    • _index:指定索引库名

    • _id指定要操作的文档id

    • { "doc" : {"field2" : "value2"} }:要更新的文档字段

#批量新增
POST /_bulk
{"index": {"_index":"hmall", "_id": "3"}}
{"info": "黑马程序员C++讲师", "email": "ww@itcast.cn", "name":{"firstName": "五", "lastName":"王"}}
{"index": {"_index":"hmall", "_id": "4"}}
{"info": "黑马程序员前端讲师", "email": "zhangsan@itcast.cn", "name":{"firstName": "三", "lastName":"张"}}



POST /_bulk
{"delete":{"_index":"hmall", "_id": "3"}}
{"delete":{"_index":"hmall", "_id": "4"}}

JavaRestClient

作用:向restful接口发送请求。

客户端初始化

1)在item-service模块中引入esRestHighLevelClient依赖:

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

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

  <properties>
      <maven.compiler.source>11</maven.compiler.source>
      <maven.compiler.target>11</maven.compiler.target>
      <elasticsearch.version>7.12.1</elasticsearch.version>
  </properties>

3)初始化RestHighLevelClient:

初始化的代码如下:

RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
        HttpHost.create("http://192.168.150.101:9200")
));

4)创建一个测试用例来实现

package com.hmall.item.es;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;

import java.io.IOException;

public class Test {
    private RestHighLevelClient client;
    //创建开始初始化函数,对客户端进行初始化

    @BeforeEach
    void setUp() {
        this.client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.21.101:9200")));
    }
    //测试代码
    @org.junit.jupiter.api.Test
    public void test(){
        System.out.println(client);
    }
    //测试用例结束后释放资源

    @AfterEach
    void tearDown() throws IOException {
        client.close();
    }
}

商品Mapping映射

分析那些字段需要添加到文档中。

根据分析编写的需求:

PUT /hmall
{
  "mappings": {
    "properties": {
      "id":{
        "type": "keyword"
      },
      "name":{
        "type": "text",
        "analyzer": "ik_smart"
      },
      "price":{
        "type": "integer"
      },
      "image":{
        "type": "keyword",
        "index": false
      },
      "category":{
        "type": "keyword"
      },
      "brand":{
        "type": "keyword"
      },
      "sold":{
        "type": "integer"
      },
      "commentCount":{
        "type": "integer",
        "index": false
      },
      "isAD":{
        "type": "boolean"
      },
      "updateTime":{
        "type": "date"
      }
    }
  }
}

索引库操作

创建索引库:

    //创建索引库
    @org.junit.jupiter.api.Test
    public void testCreateIndex() throws IOException {
        //创建Requst对象
        CreateIndexRequest request = new CreateIndexRequest("items");
        //准备参数 ,将编写的JSON字符串赋值给MAPPINF_JSON,XContentType.JSON用于指定是JSON格式
        request.source(MAPPINF_JSON, XContentType.JSON);
        //发送请求,RequestOptions.DEFAULT为是否有自定义配置,选择默认
        client.indices().create(request, RequestOptions.DEFAULT);
    }


    private final String MAPPINF_JSON = "{\n" +
            "  \"mappings\": {\n" +
            "    \"properties\": {\n" +
            "      \"id\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"name\":{\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_smart\"\n" +
            "      },\n" +
            "      \"price\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"image\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"category\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"brand\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"sold\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"commentCount\":{\n" +
            "        \"type\": \"integer\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"isAD\":{\n" +
            "        \"type\": \"boolean\"\n" +
            "      },\n" +
            "      \"updateTime\":{\n" +
            "        \"type\": \"date\"\n" +
            "      }\n" +
            "    }\n" +
            "  }\n" +
            "}";

删除索引库

    //删除索引库
    @org.junit.jupiter.api.Test
    public void testDeleteIndex() throws IOException {
        //创建Requst对象
        DeleteIndexRequest request = new DeleteIndexRequest("items");
        //发送请求
        client.indices().delete(request,RequestOptions.DEFAULT);
    }

查看索引库

    //查找索引库
    @org.junit.jupiter.api.Test
    public void testGetIndex() throws IOException {
        //创建Requst对象
        GetIndexRequest request = new GetIndexRequest("items");
        //发送2请求
//        client.indices().get(request, RequestOptions.DEFAULT);
        //由于GEt请求返回的数据较多,如果只需要判断是否存在,则使用exists方法
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println("exists = " + exists);
    }

文档操作

新增文档

由于索引库结构与数据库结构还存在一些差异,因此我们要定义一个索引库结构对应的实体。

package com.hmall.item.domain.po;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.time.LocalDateTime;

@Data
@ApiModel(description = "索引库实体")
public class ItemDoc{

    @ApiModelProperty("商品id")
    private String id;

    @ApiModelProperty("商品名称")
    private String name;

    @ApiModelProperty("价格(分)")
    private Integer price;

    @ApiModelProperty("商品图片")
    private String image;

    @ApiModelProperty("类目名称")
    private String category;

    @ApiModelProperty("品牌名称")
    private String brand;

    @ApiModelProperty("销量")
    private Integer sold;

    @ApiModelProperty("评论数")
    private Integer commentCount;

    @ApiModelProperty("是否是推广广告,true/false")
    private Boolean isAD;

    @ApiModelProperty("更新时间")
    private LocalDateTime updateTime;
}

API语法

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

可以看到与索引库操作的API非常类似,同样是三步走:

  • 1)创建Request对象,这里是IndexRequest,因为添加文档就是创建倒排索引的过程

  • 2)准备请求参数,本例中就是Json文档

  • 3)发送请求

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

    //新增文档
    @org.junit.jupiter.api.Test
    public void test() throws IOException {
        //读取数据库获取商品信息
        Item item = service.getById(317578);
        //将商品信息对象转换为Dto
        ItemDoc itemDoc = BeanUtil.copyProperties(item, ItemDoc.class);
        //将对象转换为JSON
        String jsonStr = JSONUtil.toJsonStr(itemDoc);

        //创建Requst对象
        IndexRequest request = new IndexRequest("items").id(itemDoc.getId());

        request.source(jsonStr, XContentType.JSON);

        //发送信息
        client.index(request, RequestOptions.DEFAULT);

    }

package com.hmall.item.es;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.hmall.item.domain.dto.ItemDoc;
import com.hmall.item.domain.po.Item;
import com.hmall.item.service.impl.ItemServiceImpl;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
@SpringBootTest(properties = {"spring.profiles.active=local"})
public class docTest {
    private RestHighLevelClient client;
    @Autowired
    private ItemServiceImpl service;
    //创建开始初始化函数,对客户端进行初始化

    @BeforeEach
    void setUp() {
        this.client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.21.101:9200")));
    }
    //新增文档,全局修改文档
    @org.junit.jupiter.api.Test
    public void test() throws IOException {
        //读取数据库获取商品信息
        Item item = service.getById(317578);
        //将商品信息对象转换为Dto
        ItemDoc itemDoc = BeanUtil.copyProperties(item, ItemDoc.class);
        //将对象转换为JSON
        String jsonStr = JSONUtil.toJsonStr(itemDoc);

        //创建Requst对象
        IndexRequest request = new IndexRequest("items").id(itemDoc.getId());

        request.source(jsonStr, XContentType.JSON);

        //发送信息
        client.index(request, RequestOptions.DEFAULT);

    }
    //查看文档
    @org.junit.jupiter.api.Test
    public void testGet() throws IOException {

        //创建Requst对象
        GetRequest request = new GetRequest("items","317578");

        //发送信息
        GetResponse response = client.get(request, RequestOptions.DEFAULT);

        String json = response.getSourceAsString();

        ItemDoc bean = JSONUtil.toBean(json, ItemDoc.class);
        System.out.println("bean = " + bean);

    }
    //删除文档
    @org.junit.jupiter.api.Test
    public void testdelect() throws IOException {

        //创建Requst对象
        DeleteRequest request = new DeleteRequest("items","317578");

        //发送信息
         client.delete(request, RequestOptions.DEFAULT);

    }

    //修改文档
    @org.junit.jupiter.api.Test
    public void testupdata2() throws IOException {

        //创建Requst对象
        UpdateRequest request = new UpdateRequest("items","317578");
        //数据都是独立的不是成对出现的
        request.doc(
                "price", 10000
        );

        //发送信息
        client.update(request, RequestOptions.DEFAULT);

    }


    //测试用例结束后释放资源
    @AfterEach
    void tearDown() throws IOException {
        client.close();
    }

}

批量操作文档

    //新增文档,全局修改文档
    @org.junit.jupiter.api.Test
    public void testBulk() throws IOException {
        //设置分页信息
        int size = 1000,pageNo = 1;
        //循环写入数据
        while (true){
            //读取数据库获取商品信息分页查询
            //设置当前查询条件,即状态为起售
            //创建分页对象
            Page<Item> page = service.lambdaQuery().eq(Item::getStatus, 1).page(new Page<Item>(pageNo, size));
            List<Item> records = page.getRecords();
            //判空
            if (records.isEmpty()||records == null){
                return;
            }
            //创建Requst对象
//            BulkRequest request = new BulkRequest();
//            for (Item item : records) {
//                request.add(new IndexRequest("items")
//                        .id(item.getId().toString())
//                        .source(JSONUtil.toJsonStr(BeanUtil.copyProperties(item, ItemDoc.class))),XContentType.JSON
//                );
//            }
            BulkRequest request = new BulkRequest("items");
            for (Item item : records) {
                // 2.1.转换为文档类型ItemDTO
                ItemDoc itemDoc = BeanUtil.copyProperties(item, ItemDoc.class);
                // 2.2.创建新增文档的Request对象
                request.add(new IndexRequest()
                        .id(itemDoc.getId())
                        .source(JSONUtil.toJsonStr(itemDoc), XContentType.JSON));
            }
            //发送信息
            client.bulk(request, RequestOptions.DEFAULT);
            pageNo++;
        }

    }

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

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

相关文章

微软推出的AI无代码编程微应用平台GitHub Spark和国产AI原生无代码工具CodeFlying比到底咋样?

今天咱来聊聊前阵子第十届GitHub开发者大会上发布的AI无代码编程平台GitHub Spark和国产的AI原生无代码工具CodeFlying比起来有没有什么说法。 首先说GitHub Spark这个产品截止到目前为止都很低调呀&#xff0c;甚至没有引起国外主流媒体的广泛关注。 有可能是因为大家都被…

设计模式:工厂方法模式和策略模式

工厂方法模式 什么是开闭原则? 开闭原则是扩展开发,对修改关闭 简单工厂(不是设计模式而是一种编程的习惯) 有三个角色 抽象产品:定义了产品的规范,描述了产品的特性和功能.具体产品:实现或者继承抽象产品的子类具体工厂:提供了创建产品的方法,调用者通过该方法获取产品 实…

docker:docker: Get https://registry-1.docker.io/v2/: net/http: request canceled

无数次的拉镜像让人崩溃&#xff1a; rootnode11:~/ragflow/docker# more rag.sh #export HTTP_PROXYhttp://192.168.207.127:7890 #export HTTPS_PROXYhttp://192.168.207.127:7890 #export NO_PROXYlocalhost,127.0.0.1,.aliyun.com docker compose -f docker-compose-gpu-C…

【珠海科技学院主办,暨南大学协办 | IEEE出版 | EI检索稳定 】2024年健康大数据与智能医疗国际会议(ICHIH 2024)

#IEEE出版|EI稳定检索#主讲嘉宾阵容强大&#xff01;多位外籍专家出席报告 2024健康大数据与智能医疗国际会议&#xff08;ICHIH 2024&#xff09;2024 International Conference on Health Big Data and Intelligent Healthcare 会议简介 2024健康大数据与智能医疗国际会议…

字符串处理指南:Air780E软件的全新视角

今天我会把 Air780E软件的字符串处理详细解析&#xff0c;指南如下&#xff1a; 1、Lua字符串介绍 关于字符串&#xff0c;Lua提供了一些灵活且强大的功能&#xff0c;一些入门知识如下&#xff1a; 1.1 字符串定义 在Lua中&#xff0c;字符串可以用单引号或双引号"来定…

【MySQL 保姆级教学】事务的隔离级别(详细)--下(13)

事务的隔离级别 1. 如何理解事务的隔离性2. 事务隔离级别的分类3. 查看和设置事务隔离级别3.1 全局和会话隔离级别3.2 查看和设置隔离级别 4. 事务隔离级别的演示4.1 读未提交&#xff08;Read Uncommitted&#xff09;4.2 读已提交&#xff08;Read Committed&#xff09;4.3 …

再见 阿里巴巴EasyExcel替代品EasyExcel-Plus即将诞生

最近阿里发布公告通知&#xff0c;停止对EasyExcel 更新和维护&#xff0c;EasyExcel 是一款知名的 Java Excel 工具库&#xff0c;由阿里巴巴开源&#xff0c;作者是玉霄&#xff0c;在 GitHub 上有 30k stars、7.5k forks。 据了解&#xff0c;EasyExcel作者玉霄)去年已经从…

Acrobat Pro DC 2023(pdf免费转化word)

所在位置 通过网盘分享的文件&#xff1a;Acrobat Pro DC 2023(64bit).tar 链接: https://pan.baidu.com/s/1_m8TT1rHTtp5YnU8F0QGXQ 提取码: 1234 --来自百度网盘超级会员v4的分享 安装流程 打开安装所在位置 进入安装程序 找到安装程序 进入后点击自定义安装&#xff0c;这里…

13载匠心独运,BI+AI启航新征程

13载匠心独运&#xff0c;BIAI启航新征程&#xff01; 思迈特的13年&#xff0c;是在坚守中持续创新&#xff0c;在创新中不断追求卓越&#xff0c;是在挑战与机遇并行中开创全新篇章的历程。感谢每一位陪伴走过这段旅程的人。展望未来&#xff0c;思迈特将继续以初心为舵、以…

【大数据学习 | HBASE高级】storeFile文件的合并

Compaction 操作分成下面两种&#xff1a; Minor Compaction&#xff1a;是选取一些小的、相邻的StoreFile将他们合并成一个更大的StoreFile&#xff0c;对于删除、过期、多余版本的数据不进行清除。 Major Compaction&#xff1a;是指将所有的StoreFile合并成一个StoreFile&am…

git config是做什么的?

git config是做什么的&#xff1f; git config作用配置级别三种配置级别的介绍及使用&#xff0c;配置文件说明 使用说明git confi查看参数 默认/不使用这个参数 情况下 Git 使用哪个配置等级&#xff1f; 一些常见的行为查看配置信息设置配置信息删除配置信息 一些常用的配置信…

Warped Universe游戏即将在Sui上推出,为玩家提供多样化的游戏体验

Warped Games选择Sui作为其即将推出的创新多类型游戏Warped Universe的首选Web3技术。Warped Universe让玩家可以体验第三视角实时动作、回合制策略和基地建设等玩法。该游戏使用Unreal Engine 5开发&#xff0c;将借助Sui的技术使玩家能够拥有、交易和变现其游戏内资产。 War…

Autosar CP XCP规范导读

XCP 模块在汽车电子系统架构中起到重要作用,通过与多个模块的连接,实现了数据采集、校准、诊断等功能。它通过 RTE 进行控制,通过 PDUR 进行数据路由,通过通信硬件抽象层访问底层硬件,并与操作系统和其他相关模块协同工作,确保系统的稳定运行。 主要功能用途 通信协议支…

Scala学习记录,case class,迭代器

case class case class创建的对象的属性是不可改的 创建对象&#xff0c;可以不用写new 自动重写&#xff1a;toString, equals, hashCode, copy 自动重写方法&#xff1a;toString,equals,hashCode,copy 小习一下 1.case class 的定义语法是什么 基本形式&#xff1a;case …

B2B订货系统功能设计与代码开发(PHP + MySQL)

在B2B&#xff08;Business to Business&#xff09;电子商务中&#xff0c;企业之间的商品订购、交易和供应链管理是核心功能。一个高效的B2B订货系统可以帮助企业管理库存、订单、采购等业务流程。本文将介绍一个基于PHP与MySQL技术栈的B2B订货系统的功能设计与开发流程。 一…

前端CSS3 渐变详解

文章目录 CSS3 渐变详解一、引言二、CSS3 渐变基础1、线性渐变1.1、基本线性渐变1.2、改变渐变方向 2、径向渐变2.1、基本径向渐变2.2、设置径向渐变的中心 三、高级渐变技巧1、重复渐变1.1、重复线性渐变1.2、重复径向渐变 四、总结 CSS3 渐变详解 一、引言 在现代网页设计中…

2024-11-13 Unity Addressables2——寻址资源设置

文章目录 1 设置可寻址资源2 资源组窗口2.1 资源信息2.2 右键资源选项2.3 右键分组选项2.4 创建分组2.5 配置文件2.6 Tools 工具2.7 Play Mode Script2.7 构建打包 3 补充 1 设置可寻址资源 方法一&#xff1a;勾选 Inspector 窗口中的 “Addressable”。方法二&#xff1a;选…

课程讲解--哈夫曼树:原理、特性、应用与实践

前言 在这个信息如潮水般涌动的时代&#xff0c;我&#xff0c;一篇小小的文章&#xff0c;静静地躺在某个角落&#xff0c;怀揣着一份期待&#xff0c;一份对认可的渴望。 我可能没有华丽的辞藻堆砌成的璀璨外表&#xff0c;也没有跌宕起伏如传奇故事般的情节&#xff0c;但…

HP G10服务器ESXI6.7告警提示ramdisk tmp已满

物理服务器是HP G10 VCENTER内两台服务器报错提示ramdisk"tmp"已满&#xff0c;无法写入文件 登录ESXI命令行后发现两台主机的/tmp目录都没有空间了 定位到是ams-bbUsg.txt文件占用了大量的空间 1、关闭集群的DRS功能 2、迁移当前主机上面运行的所有虚拟机至其他主…

Mysql篇-Buffer Pool中的三大链表

为什么要有 Buffer Pool&#xff1f; 虽然说 MySQL 的数据是存储在磁盘里的&#xff0c;但是也不能每次都从磁盘里面读取数据&#xff0c;这样性能是极差的。 要想提升查询性能&#xff0c;那就加个缓存。所以&#xff0c;当数据从磁盘中取出后&#xff0c;缓存内存中&#xf…