es索引库操作和使用RestHignLevelClient客户端操作es

目录

es索引库操作

mapping映射操作

索引库的CURD操作

1.创建索引库和映射

​编辑 2.查询索引库

3.删除索引库 

4.修改索引库

5.总结

 文档的CURD操作

1.新增文档 

2.查询文档 

 3.删除文档

4.修改文档

全量修改

增量修改 

5.总结

RestAPI

使用API例子 

需要的数据库表结构

 分析这个数据表的结构,然后构建索引库和mapping

 索引库结构说明:

 初始化RestClient

1.导入es的RestHighLevelClient依赖:

2.因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本,换成自己的es版本:

 3.初始化RestHighLevelClient,即维护一个bean到IoC容器

使用RestHighLevelClient构建索引库及其mapping

1.构建json数据常量

 2.创建索引库

 3.测试是否构建成功

 使用RestHighLevelClient查询索引库和删除索引库

总结

 RestClient操作文档

新增文档 

构建索引库实体类

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

 新增文档的DSL语句如下:

 代码实现

测试

 查询文档

修改文档

 删除文档

批量导入文档


es索引库操作

索引库类似于数据库中的表,mapping(映射)相当于表的结构

因此我们要向es存储数据时,必须先创建索引库和mapping(映射)

mapping映射操作

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

1.type:字段数据类型,常见的简单类型有 

  •         字符串:text(可分词文本),keyword(精确词,不可进行分词)
  •         数值:integer,long,short,byte,double,float
  •         布尔值:boolean
  •         日期:date
  •         对象:object

2.index:是否为这个字段创建索引,默认为true

3.analyzer:这个字段使用哪种分词器(前提为type类型的text可分词文本)

4.properties:该字段的子字段

例如下面的json文档:

{
    "age": 21,
    "weight": 52.1,
    "isMarried": false,
    "info": "我是最厉害的",
    "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;无需分词器

索引库的CURD操作

这里我们使用Kibana编写DSL的方式来演示。 

1.创建索引库和映射

基本语法:

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

 2.查询索引库

基本语法

  • 请求方式:GET

  • 请求路径:/索引库名

  • 请求参数:无

GET /person 

 

3.删除索引库 

语法:

  • 请求方式:DELETE

  • 请求路径:/索引库名

  • 请求参数:无

 DELETE /person

 

查询不到person索引库

 

4.修改索引库

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

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

 

再次查询,birthday字段已经添加成功

 

5.总结

索引库操作有哪些?

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

 文档的CURD操作

我们在数据库中创建了一张数据表,和表的结构后,是不是要开始向表中插入数据了。

在索引库中也是这样,我们已经创建了索引库,并设置了mapping(映射),现在我们要向索引库中插入文档数据

1.新增文档 

语法:

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

 

显示创建成功即,增加成功

 

2.查询文档 

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

语法

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

例子 

#查询索引库的id为1的文档
GET /person/_doc/1

 3.删除文档

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

语法:

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

 例子

DELETE /person/_doc/1

4.修改文档

修改有两种方式:

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

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

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

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

语法:

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

增量修改 

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

 语法:

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

例子:修改姓名

#增量修改
POST /person/_update/1
{
  "doc":{
    "name":{"lastName":"何"}
  }
}

5.总结

文档操作有哪些?

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

RestAPI

ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求发送给ES。官方文档地址:Elasticsearch Clients | Elastic

其中的Java Rest Client又包括两种:

  • Java Low Level Rest Client
  • Java High Level Rest Client

这里使用的是Java HighLevel Rest Client客户端API 

使用API例子 

需要的数据库表结构

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

创建索引库,最关键的是mapping映射,而mapping映射要考虑的信息包括:

  • 字段名
  • 字段数据类型
  • 是否参与搜索(是否需要index索引)
  • 是否需要分词
  • 如果分词,分词器是什么?

其中:

  • 字段名、字段数据类型,可以参考数据表结构的名称和类型
  • 是否参与搜索要分析业务来判断,例如图片地址,就无需参与搜索
  • 是否分词呢要看内容,内容如果是一个整体就无需分词,反之则要分词
  • 分词器,我们可以统一使用ik_max_word

这是分析出来的索引库结构

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"
      }
    }
  }
}

 索引库结构说明:
 

这里将name,brand,city字段都使用了mapping的copy_to属性复制到了all字段。

复制的原因是:我们并不知道用户进行搜索时是根据酒店的名字还是品牌还是城市进行搜索的,如果在三个字段中进行匹配搜索,对es的开销十分大,所以我们把这三个字段合并成一个all字段,这样一来,用户进行搜索时,我们只需要在all字段进行文档匹配,获取对应的id即可 ,但是对每个字段的是否分词还是原来的形式,如name进行最细分词,brand,city都不进行分词

这里设置了location字段,它的type类型是geo_point类型,这是es提供的包括了维度,精度的数据类型

 初始化RestClient

在elasticsearch提供的API中,与elasticsearch一切交互都封装在一个名为RestHighLevelClient的类中,必须先完成这个对象的初始化,建立与elasticsearch的连接。 

1.导入es的RestHighLevelClient依赖:

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

2.因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本,换成自己的es版本:

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

 3.初始化RestHighLevelClient,即维护一个bean到IoC容器

    //定义操作es的客户端对象
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        return new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.230.100:9200")));
    }

使用RestHighLevelClient构建索引库及其mapping

代码分为三步:

  • 1)创建Request对象。因为是创建索引库的操作,因此Request是CreateIndexRequest。
  • 2)添加请求参数,其实就是DSL的JSON参数部分。因为json字符串很长,这里是定义了静态字符串常量HOTEL_MAPPING,让代码看起来更加优雅。
  • 3)发送请求,client.indices()方法的返回值是IndicesClient类型,封装了所有与索引库操作有关的方法。

1.构建json数据常量

public class HotelConstant {
    public static final String HOTEL_MAPPING="{\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" +
            "}";
}

 2.创建索引库

/**
 * 测试索引库功能
 */
@SpringBootTest
public class TestIndex {
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Test
    public void test01() throws IOException {
        //构建 创建索引库请求对象,参数为索引库对象
        CreateIndexRequest request = new CreateIndexRequest("hotel");
        //设置DSL语句,第一个参数为构建mapping的json语句,第二个参数是表明这是JSON数据格式
        request.source(HotelConstant.HOTEL_MAPPING, XContentType.JSON);
        //发起请求
        CreateIndexResponse result = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        boolean isSuccess = result.isAcknowledged();
        System.out.println(isSuccess?"构建索引库成功":"构建索引库失败");
    }
}

 3.测试是否构建成功

GET /hotel

 使用RestHighLevelClient查询索引库和删除索引库

    /**
     * 判断索引库是否存在
     */
    @Test
    public void test02() throws IOException {
        //构建 获取索引库请求对象,参数为索引库名字
        GetIndexRequest request = new GetIndexRequest("hotel");
        //查询不用写dsl语句
        //直接发起请求,判断索引库是否存在
        boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println(exists?"hotel索引库存在":"hotel索引库不存在");
    }
    /**
     * 删除索引库
     */
    @Test
    public void test03() throws IOException {
        //构建 删除索引库请求对象,参数为索引库对象
        DeleteIndexRequest request = new DeleteIndexRequest("hotel");
        //删除不用写dsl语句
        //直接发起请求,删除索引库
        AcknowledgedResponse result = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
        boolean isSuccess = result.isAcknowledged();
        System.out.println(isSuccess?"删除成功":"删除失败");
    }

总结

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

索引库操作的基本步骤:

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

 RestClient操作文档

新增文档 

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

构建索引库实体类

数据库查询后的结果是一个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
因此,我们需要定义一个新的类型,与索引库结构吻合:
@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();
    }
}
 新增文档的DSL语句如下:
POST /{索引库名}/_doc/1
{
    "name": "Jack",
    "age": 21
}
 代码实现
@SpringBootTest
public class TestDoc {
    @Autowired
    private HotelMapper hotelMapper;
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Test
    public void test01() throws IOException {
        //使用mapper去数据库中查询数据
        Hotel hotel = hotelMapper.selectById(36934L);
        //封装成HotelDoc类
        HotelDoc hotelDoc = new HotelDoc(hotel);
        //序列化成json数据,当作DSL语句
        String jsonDSL = JSON.toJSONString(hotelDoc);

        //构建 文档请求对象,第一个参数是索引库名字,第二个是文档id
        IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId()+"");
        //设置DSL语句
        request.source(jsonDSL, XContentType.JSON);
        //发送请求
        IndexResponse result = restHighLevelClient.index(request, RequestOptions.DEFAULT);
        System.out.println(result);
    }
}
测试

GET /hotel/_doc/36934

    /**
     * 获取文档信息
     */
    @Test
    public void test02() throws IOException {
        //构建 查询文档请求对象
        GetRequest request = new GetRequest("hotel", "36934");
        //查询不用写DSL语句
        //直接发送请求
        GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
        //获取响应的json数据
        String jsonData = response.getSourceAsString();
        //将json数据反序列化成对象
        HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
        System.out.println(hotelDoc);
    }

 查询文档

查询的DSL语句如下:

GET /hotel/_doc/{id}
    /**
     * 获取文档信息
     */
    @Test
    public void test02() throws IOException {
        //构建 查询文档请求对象
        GetRequest request = new GetRequest("hotel", "36934");
        //查询不用写DSL语句
        //直接发送请求
        GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
        //获取响应的json数据
        String jsonData = response.getSourceAsString();
        //将json数据反序列化成对象
        HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
        System.out.println(hotelDoc);
    }

修改文档

修改我们讲过两种方式:

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

在RestClient的API中,全量修改与新增的API完全一致,判断依据是ID:

  • 如果新增时,ID已经存在,则修改
  • 如果新增时,ID不存在,则新增

所以我们主要关注增量修改。

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

  • 1)准备Request对象。这次是修改,所以是UpdateRequest
  • 2)准备参数。也就是JSON文档,里面包含要修改的字段
  • 3)更新文档。这里调用client.update()方法
 /**
     * 增量修改文档的部分信息
     */
    @Test
    public void test03() throws IOException {
        //构建 更新文档的请求对象
        UpdateRequest request = new UpdateRequest("hotel", "36934");
        //编写DSL语句
        request.doc("city","天津");
        //发送请求
        UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
    }

 删除文档

    /**
     * 删除文档
     */
    @Test
    public void test04() throws IOException {
        //构建 删除文档请求对象
        DeleteRequest request = new DeleteRequest("hotel", "36934");
        //直接发送请求
        restHighLevelClient.delete(request,RequestOptions.DEFAULT);
    }

批量导入文档

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

步骤如下:

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

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

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

 /**
     * 批量导入数据
     */
    @Test
    public void test05() throws IOException {
        //使用mapper查询到所有数据
        List<Hotel> hotels = hotelMapper.selectList(null);
        BulkRequest bulkRequest = new BulkRequest("hotel");
        hotels.stream().forEach(hotel -> {
            //把hotel变成hotelDoc类对象,并序列化成json数据
            String jsonDSL = JSON.toJSONString(new HotelDoc(hotel));
            //构建 新增文档请求对象
            IndexRequest request = new IndexRequest("hotel").id(hotel.getId()+"").source(jsonDSL, XContentType.JSON);
            //将请求对象添加到bulkRequest中
            bulkRequest.add(request);
        });
        //发送请求
        restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
    }

成功导入es 

GET /hotel/_search
{
  "query": {
    "match_all": {}
  }
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Android】Jetpack入门知识总结(LifeCycle,ViewModel,LiveData,DataBinding等)

文章目录 LifeCycle使用Lifecycle解耦页面与组件自定义控件实现LifecycleObserver接口注册生命周期监听器 使用LifecycleService解耦Service与组件使用ProcessLifecycleOwner监听应用程序生命周期 ViewModel用法在 Fragment 中使用 ViewModel LiveDataDataBinding导入依赖基本用…

构建后端为etcd的CoreDNS的容器集群(二)、下载最新的etcd容器镜像

在尝试获取etcd的容器的最新版本镜像时&#xff0c;使用latest作为tag取到的并非最新版本&#xff0c;本文尝试用实际最新版本的版本号进行pull&#xff0c;从而取到想的最新版etcd容器镜像。 一、用latest作为tag尝试下载最新etcd的镜像 1、下载镜像 [rootlocalhost opt]# …

找到连续赢 K 场比赛的第一位玩家

题目链接 找到连续赢 K 场比赛的第一位玩家 题目描述 注意 2 < n < 10^51 < skills[i] < 10^6skills 中的整数互不相同这个比赛的赢家是第一位连续赢下k场比赛的玩家 解答思路 双指针&#xff0c;一个指针maxIdx指向当前技能等级最高的玩家&#xff0c;另一个…

pagehelper 开启分页查询之后为什么total返回有误

场景重现 在controller中 使用了pageHelper 分页之后,巡查结果的确是10个,但是为什么total永远都是10?debug发现 没法获取到原本的total,获取的是list的长度热心网友的回答 网上的原因是:TableDataInfo(list)list的泛型是 T类型,但是Mapper中返回的List的泛型是M看了一…

想让前后端交互更轻松?alovajs了解一下?

作为一个前端开发者&#xff0c;我最近发现了一个超赞的请求库 alovajs&#xff0c;它真的让我眼前一亮&#xff01;说实话&#xff0c;我感觉自己找到了前端开发的新大陆。大家知道&#xff0c;在前端开发中&#xff0c;处理 Client-Server 交互一直是个老大难的问题&#xff…

如何提取视频文件中的音频(.mp4 to .mp3)

1.安装 FFmpeg&#xff08;windows 为例&#xff09; 官网地址 第一步 点击 windows 版 第二步 解压下载好的 .zip文件 第三步 解压之后进入 bin 目录下 第四步 点击导航栏 输入 cmd 回车 第五步 输入指令 ffmpeg -i input_video.mp4 -q:a 0 -map a output_audio.mp3将上面…

算法题总结(十六)—— 动态规划(上)

动态规划 动态规划理论基础 什么是动态规划 动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一问题有很多重叠子问题&#xff0c;使用动态规划是最有效的。 所以动态规划中每一个状态一定是由上一个状态推导出来的&#xff…

实战 | 国外攻破大学数据库系统,暴露数千学生记录

实战 | 国外攻破大学数据库系统&#xff0c;暴露数千学生记录 引言 在这篇文章中&#xff0c;我将分享我是如何攻破一个大型大学解决方案门户服务器的&#xff0c;这个服务器服务于许多大学客户&#xff0c;并且涉及数千名学生的数据。 目标 这是一个由印度许多大学和学院使…

没有基础,学习HCIE难吗?

首先要清楚&#xff0c;华为 HCIE-Datacom 认证并非局限于特定专业背景&#xff0c;即便对专业基础有一定要求&#xff0c;无论你有无相关学习经历或者工作经验&#xff0c;皆有机会报考并争取通过这一认证。HCIE-Datacom 考试主要由笔试和实验两部分构成&#xff0c;涉及高级路…

elf加载,动态库加载

elf加载 ELF&#xff08;Executable and Linkable Format&#xff0c;可执行与可链接格。 所以我们写代码生成的可执行文件&#xff0c;以及写的动态库都是elf格式的文件。 我们重点要关注的就是红色框框里面的section节。 而节保存的就有我们的代码段和数据段。所以我们链接…

Redis 性能优化选择:Pika 的配置与使用详解

引言 在我们日常开发中 redis是我们开发业务场景中不可缺少的部分。Redis 凭借其内存存储和快速响应的特点&#xff0c;广泛应用于缓存、消息队列等各种业务场景。然而&#xff0c;随着数据量的不断增长&#xff0c;单节点的 Redis 因为内存限制和并发能力的局限&#xff0c;逐…

ONLYOFFICE文档8.2:开启无缝PDF协作

ONLYOFFICE 开源办公套件的最新版本新增约30个新功能&#xff0c;并修复了超过500处故障。 什么是 ONLYOFFICE 文档 ONLYOFFICE 文档是一套功能强大的文档编辑器&#xff0c;支持编辑处理文档、表格、幻灯片、可填写的表单和PDF。可多人在线协作&#xff0c;支持插件和 AI 集…

论文解读 | ECCV2024 AutoEval-Video:一个用于评估大型视觉-语言模型在开放式视频问答中的自动基准测试...

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 点击 阅读原文 观看作者讲解回放&#xff01; 作者简介 陈修元&#xff0c;上海交通大学清源研究院硕士生 概述 总结来说&#xff0c;我们提出了一个新颖且具有挑战性的基准测试AutoEvalVideo&#xff0c;用于全…

红队-安全见闻篇(上)

声明 学习视频来自B站UP主 泷羽sec的个人空间-泷羽sec个人主页-哔哩哔哩视频,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 一.编程与开发 1.后端语言学习 C语⾔&#xff1a;⼀种通⽤的…

NVR小程序接入平台/设备EasyNVR多个NVR同时管理的高效解决方案

在当今的数字化安防时代&#xff0c;视频监控系统的需求日益复杂和多样化。为了满足不同场景下的监控需求&#xff0c;一种高效、灵活且兼容性强的安防视频监控平台——NVR批量管理软件/平台EasyNVR应运而生。本篇探讨这一融合所带来的创新与发展。 一、NVR监测软件/设备EasyNV…

053_python基于深度学习的短视频内容理解与推荐系统

目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍&#xff1a;CodeMentor毕业设计领航者、全网关注者30W群落&#xff0c;InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者&#xff0c;博客领航之星、开发者头条/腾讯云/AW…

如何实现海内外工厂的EDI对接?

企业在国际市场的扩张需要高效的信息流动&#xff0c;以便快速响应客户需求。但国内工厂和海外工厂使用的系统可能存在兼容性问题&#xff0c;且数据格式各不相同&#xff0c;集成过程复杂。 近期国内主营高精度滚动轴承的汽车行业C公司就遇到了这样的挑战&#xff0c;如何实现…

linux查看文件命令

查看文件命令 显示命令 cat 语法&#xff1a;cat 【选项】 文件 选项 命令含义n显示行号包括空行b显示行号不包括空行s压缩空行为一行A显示隐藏字符 cat -n 文件&#xff1a;显示行号包括空行 cat -b 文件 cat -s 文件 cat -A 文件 more和less是 分页查看 tac和rev都…

python实战项目47:Selenium采集百度股市通数据

python实战项目47:Selenium采集百度股市通数据 一、思路分析二、完整代码一、思路分析 这里以获取百度股市通股评下的投票数据为例,页面中的其他数据同理。由于此页面数据是js动态加载的,所以采用Selenium获取数据。思路很简单,通过Selenium打开页面,然后定位到“股评”选…

502 错误码通常出现在什么场景?

服务器过载场景 高流量访问&#xff1a;当网站遇到突发的高流量情况&#xff0c;如热门产品促销活动、新闻热点事件导致网站访问量激增时&#xff0c;服务器可能会因承受过多请求而无法及时响应。例如&#xff0c;电商平台在 “双十一” 等购物节期间&#xff0c;大量用户同时…