Elastic Search(ES)Java 入门实操(2)搜索代码

上篇解释了 ES 的基本概念和分词器。Elastic Search (ES)Java 入门实操(1)下载安装、概念-CSDN博客

Elastic Search(ES)Java 入门实操(3)数据同步-CSDN博客

这篇主要演示 Java 整合 ES进行数据搜索。

ES 实现搜索接口

首先根据 MySQL 字段,在 ES 创建索引。

create table mydb
(
    id          int auto_increment comment '序号'
        primary key,
    title       varchar(20)                        not null comment '标题',
    content     text                               not null comment '内容',
    cretateTime datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    updateTime  datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
    isDelete    tinyint  default 0                 not null comment '是否删除'
)
    comment '文章' collate = utf8mb4_unicode_ci;
PUT article_1
{
  "aliases": {  #别名
    "article": {}
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text", #字段类型
        "analyzer": "ik_max_word",#插入时分词方式
        "search_analyzer": "ik_smart", #查询时分词方式
        "fields": { #字段配置,子字段
          "keyword": { 
            "type": "keyword", #精确匹配
            "ignore_above": 256 #超过 256 字符就忽略查询
          }
        }
      },
      "content": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "createTime": {
        "type": "date"
      },
      "updateTime": {
        "type": "date"
      },
      "isDelete": {
        "type": "keyword"
      }
    }
  }
}

引入 spring-data-elasticsearch 依赖

需要注意版本号一定要兼容

Spring Data Elasticsearch - Reference Documentation

这里使用的是 7.17版本,所以选择相近的 4.4.x版本的 依赖,同样的 springboot 的版本也得严格对应。Maven Repository: org.springframework.data » spring-data-elasticsearch » 4.4.7 (mvnrepository.com)

 下面的报错就是版本不对,需要把springboot 改为 2.7+,

java.lang.NoSuchFieldError: INDEX_CONTENT_TYPE
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-elasticsearch -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-elasticsearch</artifactId>
    <version>4.4.7</version>
</dependency>

启动 springboot,有调用的日志

给 ES 索引创建实体类 

/**
 * ES 实体类
 * document 注解是将Java 对象映射到 Elasticsearch 索引和类型中
 */
@Document(indexName = "article")
@Data
public class ArticleEsDto implements Serializable {
    private static final String DATE_TIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";

    /**
     * id
     * 需要打上 id 注解,指定 ES 中存储的 id 是唯一字段
     * 如果新增是不传入,则 ES 会自动生成
     */
    @Id
    private long id;
    /**
     * 标题
     */
    private String title;

    /**
     * 内容
     */
    private String content;

    /**
     * 创建时间
     */
    @Field(index = false, store = true,type = FieldType.Date,format = {},pattern = DATE_TIME_PATTERN)
    private Date createTime;

    /**
     * 更新时间
     * Field:这是一个MyBatis-Plus注解,用于标注该字段在数据库表中的对应关系。
     * 其中,index = false表示该字段不在数据库表的索引中,
     * store = true表示该字段在数据库表的存储中,
     * type = FieldType.Date表示该字段的类型为Date,
     * format = {}表示该字段的格式为空,
     * pattern = DATE_TIME_PATTERN表示该字段的日期时间格式为DATE_TIME_PATTERN。
     */
    @Field(index = false, store = true,type = FieldType.Date,format = {},pattern = DATE_TIME_PATTERN)
    private Date updateTime;

    /**
     * 是否删除
     */
    private Integer isDelete;

    private static final long serialVersionUID = 1L;
}

第一种方式

elasticsearch Respository,新建类继承该类,默认提供了简单的增删改查方法,多用于可以预期的,相对不复杂的查询

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
    <S extends T> S save(S entity);

    <S extends T> Iterable<S> saveAll(Iterable<S> entities);

    Optional<T> findById(ID id);

    boolean existsById(ID id);

    Iterable<T> findAll();

    Iterable<T> findAllById(Iterable<ID> ids);

    long count();

    void deleteById(ID id);

    void delete(T entity);

    void deleteAllById(Iterable<? extends ID> ids);

    void deleteAll(Iterable<? extends T> entities);

    void deleteAll();
}
/**
 * ES 的控制层
 * 继承 ElasticsearchRepository 即可
 */
public interface ArticleEsDao extends ElasticsearchRepository<ArticleEsDto, Long> {

    // 这里可以扩展一些自定义方法
    // 例如:根据标题模糊查询
    List<ArticleEsDto> findByTitle(String title);

}

新增测试

//注入接口
    @Resource
    private ArticleEsDao articleEsDao;
    
    //测试新增
    @Test
    void EsTest1(){
        //创建实体对象并添加属性
        ArticleEsDto articleEsDto = new ArticleEsDto();
        articleEsDto.setId(1L);
        articleEsDto.setTitle("青花瓷");
        articleEsDto.setContent("天青色等烟雨而我在等你");
        articleEsDto.setCreateTime(new Date());
        articleEsDto.setUpdateTime(new Date());
        articleEsDto.setIsDelete(0);
        //调用方法保存
        articleEsDao.save(articleEsDto);
        System.out.println(articleEsDto.getId());
    }

dev tools 查看

GET article/_search/

自定义方法测试

我们在上面创建接口的时候创建了一个根据标题查询的方法

    @Test
    void EsTest2(){
        List<ArticleEsDto> articleEsDtos = articleEsDao.findByTitle("青花瓷");
        System.out.println(articleEsDtos);
    }

 第二种方式

spring 默认提供了操作 ES 的客户端对象 ElasticSearchRestTemplate,同样提供了增删改查,更加灵活,适用于更加复杂的操作,返回结果更加完整,但是需要自己解析。

    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

提示,在编写查询条件以及处理数据时,可以先在 Dev Tools 中执行一下查询,没问题之后再进行代码层面的条件编写。

查询 DSL

官方文档:Query and filter context | Elasticsearch Guide [8.14] | Elastic

查询模式:Boolean query | Elasticsearch Guide [8.14] | Elastic

GET /_search
{
  "query": {  
    "bool": {  //组合条件
      "must": [ //必须匹配
        { "match":  // 模糊匹配{ "title":   "Search"        }},
        { "match": { "content": "Elasticsearch" }}
      ],
      "filter": [ //
        { "term": //精确匹配 { "status": "published" }},
        { "range": //范围匹配 { "publish_date": { "gte": "2015-01-01" }}}
      ]
    }
  }
}

除了 must ,filter,还有 must_not,必须不存在才能匹配,should,至少有多少个条件相符才匹配,同时还有一个参数 minimum_should_match 满足最小的条件数,比如 1,至少满足一个条件才能查询到,比如标题和描述存在一个就可以返回结果。

POST _search
{
  "query": {
    "bool" : {
      "must" : {
        "term" : { "user.id" : "kimchy" }
      },
      "filter": {
        "term" : { "tags" : "production" }
      },
      "must_not" : {
        "range" : {
          "age" : { "gte" : 10, "lte" : 20 }
        }
      },
      "should" : [
        { "term" : { "tags" : "env1" } },
        { "term" : { "tags" : "deployed" } }
      ],
      "minimum_should_match" : 1,
      "boost" : 1.0
    }
  }
}

需要注意的是,通过模糊查询之后,查询结果中有一个参数是 max_score,表示这条数据和搜索条件的最高匹配度。

在 Java 中编写查询条件以及处理查询的数据。

主要使用到的 API

//查询条件构造器
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

//排序条件构造器
SortBuilder<?> sortBuilder = SortBuilders.scoreSort();

//分页
PageRequest pageRequest = PageRequest.of((int) current, (int) pageSize);

//组合查询条件
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder)
                .withPageable(pageRequest).withSorts(sortBuilder).build();
//调用 elasticsearchRestTemplate 查询
SearchHits<PostEsDTO> searchHits = elasticsearchRestTemplate.search(searchQuery, PostEsDTO.class);

完整代码

/**
 * 从 es 查询数据
 */
@Service
public class ArticleEsManager {

    @Resource
    private ArticleMapper articleMapper;


    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    public Page<Article> searchByEs(ArticleQueryRequest articleQueryRequest) {
        //提取查询参数
        Long id = articleQueryRequest.getId();
        String searchText = articleQueryRequest.getSearchText();
        String content = articleQueryRequest.getContent();
        String title = articleQueryRequest.getTitle();
        //设置分页参数,起始页为 0
        int current = articleQueryRequest.getCurrent() -1 ;
        int pageSize = articleQueryRequest.getPageSize();
        String sortField = articleQueryRequest.getSortField();
        String sortOrder = articleQueryRequest.getSortOrder();
        //构建布尔查询,创建 boolqueryBuilder,用于后续查询条件构建
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //过滤查询条件
        //过滤掉被逻辑删除的 term 是精确匹配
        boolQueryBuilder.filter(QueryBuilders.termQuery("isDelete",0));
        //id必须精确匹配
        if(id!=null){
            boolQueryBuilder.filter(QueryBuilders.termQuery("id",id));
        }
        //模糊查询,按照查询词(关键词)检索
        if(StringUtils.isNotEmpty(searchText)){
            boolQueryBuilder.should(QueryBuilders.matchQuery("title",searchText));
            boolQueryBuilder.should(QueryBuilders.matchQuery("content",searchText));
            //设置至少多少匹配才进行查询
            boolQueryBuilder.minimumShouldMatch(1);
        }
        //根据标题检索
        if(StringUtils.isNotEmpty(title)){
            boolQueryBuilder.should(QueryBuilders.matchQuery("title",title));
            boolQueryBuilder.minimumShouldMatch(1);
        }
        //根据内容检索
        if(StringUtils.isNotEmpty(content)){
            boolQueryBuilder.should(QueryBuilders.matchQuery("content",searchText));
            //设置至少多少匹配才进行查询
            boolQueryBuilder.minimumShouldMatch(1);
        }
        //进行排序
        //对查询结果的分数进行排序
        SortBuilder<?> sortBuilder = SortBuilders.scoreSort();
        if (StringUtils.isNotEmpty(sortField) && StringUtils.isNotEmpty(sortOrder)){
            sortBuilder = SortBuilders.fieldSort(sortField);
            sortBuilder.order(CommonConstant.SORT_ORDER_ASC.equals(sortOrder) ? SortOrder.ASC:SortOrder.DESC);
        }
        //分页
        PageRequest pageRequest = PageRequest.of(current, pageSize);
        //构造查询
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder)
                .withPageable(pageRequest).withSorts(sortBuilder).build();
        //调用 elasticsearchRestTemplate 执行查询
        SearchHits<ArticleEsDto> searchHits = elasticsearchRestTemplate.search(searchQuery, ArticleEsDto.class);
        System.out.println(searchHits);
        Page<Article> page = new Page<>();
        page.setTotal(searchHits.getTotalHits());
        //新建集合存储文章
        List<Article> resourceList = new ArrayList<>();
        //处理结果,判断是否有搜索结果
        if(searchHits.hasSearchHits()){
            //获取结果列表
            List<SearchHit<ArticleEsDto>> searchHits1 = searchHits.getSearchHits();
            System.out.println(searchHits1);
            //获取结果的id,使用id在数据库中查询
            List<Long> ids = searchHits1.stream().map(searchHit -> searchHit.getContent().getId()).collect(Collectors.toList());
            List<Article> articles = articleMapper.selectBatchIds(ids);
            //将查询结果与数据库查询结果进行匹配
            if (CollectionUtils.isNotEmpty(articles)) {
                //将查询结果与数据库查询结果进行匹配
                Map<Long, List<Article>> collect = articles.stream().collect(Collectors.groupingBy(Article::getId));
                //遍历文章id
                articles.forEach(articleId -> {
                    if(collect.containsKey(articleId)){
                        resourceList.add(collect.get(articleId).get(0));
                    }else{
                        // 从 es 清空 db 已物理删除的数据
                        String delete = elasticsearchRestTemplate.delete(String.valueOf(articleId), ArticleEsDto.class);
                    }
                });
            }
        }
        page.setRecords(resourceList);
        return page;
    }
}

成功查询到数据 

完整代码

/**
 * 从 es 查询数据
 */
@Service
public class ArticleEsManager {

    @Resource
    private ArticleMapper articleMapper;


    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;


    public Page<Article> searchByEs(ArticleQueryRequest articleQueryRequest) {
        //提取查询参数
        Long id = articleQueryRequest.getId();
        String searchText = articleQueryRequest.getSearchText();
        String content = articleQueryRequest.getContent();
        String title = articleQueryRequest.getTitle();
        //设置分页参数,起始页为 0
        int current = articleQueryRequest.getCurrent() -1 ;
        int pageSize = articleQueryRequest.getPageSize();
        String sortField = articleQueryRequest.getSortField();
        String sortOrder = articleQueryRequest.getSortOrder();
        //构建布尔查询,创建 boolqueryBuilder,用于后续查询条件构建
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //过滤查询条件
        //过滤掉被逻辑删除的 term 是精确匹配
        boolQueryBuilder.filter(QueryBuilders.termQuery("isDelete",0));
        //id必须精确匹配
        if(id!=null){
            boolQueryBuilder.filter(QueryBuilders.termQuery("id",id));
        }
        //模糊查询,按照查询词(关键词)检索
        if(StringUtils.isNotEmpty(searchText)){
            boolQueryBuilder.should(QueryBuilders.matchQuery("title",searchText));
            boolQueryBuilder.should(QueryBuilders.matchQuery("content",searchText));
            //设置至少多少匹配才进行查询
            boolQueryBuilder.minimumShouldMatch(1);
        }
        //根据标题检索
        if(StringUtils.isNotEmpty(title)){
            boolQueryBuilder.should(QueryBuilders.matchQuery("title",title));
            boolQueryBuilder.minimumShouldMatch(1);
        }
        //根据内容检索
        if(StringUtils.isNotEmpty(content)){
            boolQueryBuilder.should(QueryBuilders.matchQuery("content",searchText));
            //设置至少多少匹配才进行查询
            boolQueryBuilder.minimumShouldMatch(1);
        }
        //进行排序
        //对查询结果的分数进行排序
        SortBuilder<?> sortBuilder = SortBuilders.scoreSort();
        if (StringUtils.isNotEmpty(sortField) && StringUtils.isNotEmpty(sortOrder)){
            sortBuilder = SortBuilders.fieldSort(sortField);
            sortBuilder.order(CommonConstant.SORT_ORDER_ASC.equals(sortOrder) ? SortOrder.ASC:SortOrder.DESC);
        }
        //分页
        PageRequest pageRequest = PageRequest.of(current, pageSize);
        //构造查询
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder)
                .withPageable(pageRequest).withSorts(sortBuilder).build();
        //调用 elasticsearchRestTemplate 执行查询
        SearchHits<ArticleEsDto> searchHits = elasticsearchRestTemplate.search(searchQuery, ArticleEsDto.class);
        System.out.println(searchHits);
        Page<Article> page = new Page<>();
        page.setTotal(searchHits.getTotalHits());
        //新建集合存储文章
        List<Article> resourceList = new ArrayList<>();
        //处理结果,判断是否有搜索结果
        if(searchHits.hasSearchHits()){
            //获取结果列表
            List<SearchHit<ArticleEsDto>> searchHits1 = searchHits.getSearchHits();
            System.out.println(searchHits1);
            //获取结果的id,使用id在数据库中查询
            List<Long> ids = searchHits1.stream().map(searchHit -> searchHit.getContent().getId()).collect(Collectors.toList());
            List<Article> articleList = articleMapper.selectBatchIds(ids);
            //将查询结果与数据库查询结果进行匹配
            if (CollectionUtils.isNotEmpty(articleList)) {
                //将查询结果与数据库查询结果进行匹配
                Map<Long, List<Article>> collect = articleList.stream().collect(Collectors.groupingBy(Article::getId));
                //遍历文章id
                ids.forEach(articleId -> {
                    if(collect.containsKey(articleId)){
                        resourceList.add(collect.get(articleId).get(0));
                    }else{
                        // 从 es 清空 db 已物理删除的数据
                        String delete = elasticsearchRestTemplate.delete(String.valueOf(articleId), ArticleEsDto.class);
                    }
                });
            }
        }
        //设置到分页里
        page.setRecords(resourceList);
        return page;
    }

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

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

相关文章

HQL面试题练习 —— 求连续段的最后一个数及每个连续段的个数

目录 1 题目2 建表语句3 题解 题目来源&#xff1a;拼多多。 1 题目 有一张表t_id记录了id&#xff0c;id不重复&#xff0c;但是会存在间断&#xff0c;求出连续段的最后一个数及每个连续段的个数。 ----- | id | ----- | 1 | | 2 | | 3 | | 5 | | 6 | | 8 | | …

C++11:列表初始化 初始化列表initializer_list decltype关键字 左值右值 std::move

目录 前言 列表初始化 初始化列表initializer_list decltype关键字 左值和右值 move 前言 2003年C标准委员会曾经提交了一份技术勘误表&#xff08;简称TC1&#xff09;&#xff0c;使得C03这个名字取代了C98成为了C11前最新的C标准名称。不过由于C03主要是对C98标准中的…

Directory Opus 13.6 可用的apk文件右键菜单脚本

// apk文件的右键经过adb安装的脚本,可以在多个设备中选择function OnClick(clickData) {try {// 检查是否选中了文件if (clickData.func.sourcetab.selected_files.count 0) {DOpus.Output("没有选中任何文件");return;}// 获取选中的文件名var selectedFile clic…

聆思CSK6大模型开发板英语评测类开源SDK详解

离线英文评测算法SDK 能力简介 CSK6 大模型开发套件可以对用户通过语音输入的英文单词进行精准识别&#xff0c;并对单词的发音、错读、漏读、多读等方面进行评估&#xff0c;进行音素级的识别&#xff0c;根据用户的发音给出相应的建议和纠正&#xff0c;帮助用户更好地掌握单…

Java学习书籍推荐

本文推荐了Java基础&#xff0c;并发&#xff0c;虚拟机学习过程中&#xff0c;比较好的书籍&#xff0c;如果大家需要视频教程&#xff0c;可参考【软件开发】Java学习路线 或者B站文件夹同时会收藏其他Java视频&#xff0c;感谢关注。 指路&#xff1a;Java学习-创建者&…

全光网络与传统网络架构的对比分析

随着信息技术的飞速发展&#xff0c;网络已经成为我们日常生活中不可或缺的一部分。在这个信息爆炸的时代&#xff0c;全光网络和传统网络架构作为两种主流的网络技术&#xff0c;各有其特点和适用范围。本文将对这两种网络架构进行详细的对比分析&#xff0c;帮助读者更好地了…

【TB作品】MSP430F5529 单片机,简单电子琴

使用MSP430制作一个简单电子琴 作品功能 这个项目基于MSP430单片机&#xff0c;实现了一个简单的电子琴。通过按键输入&#xff0c;电子琴可以发出对应的音符声音。具体功能包括&#xff1a; 按下按键时发出对应音符的声音。松开按键时停止发声。支持C调低音、中音和高音。 …

nomachine使用记录以及录包

录包命令&#xff1a; rosbag record 话题名字&#xff08;可以是原相机话题和执行程序的话题&#xff09;rosbag play 包名&#xff08;可以离线播放包的数据&#xff09; rqt_image_view 话题可视化

从VS Code源码看清晰代码之美

VS Code的产品做的很优秀&#xff0c;其源码也质量颇高&#xff0c;清晰、整洁、富有美感。 下面是 src\vs\workbench\common\notifications.ts 文件中的两段代码&#xff0c;大家感受一下&#xff1a; get sticky(): boolean {if (this._sticky) {return true; // explicitl…

2024上海初中生古诗文大会倒计时4个多月:单选题真题和独家解析

现在距离2024年初中生古诗文大会还有4个多月时间&#xff0c;我们继续来看10道选择题真题和详细解析&#xff0c;以下题目截取自我独家制作的在线真题集&#xff0c;都是来自于历届真题&#xff0c;去重、合并后&#xff0c;每道题都有参考答案和解析。 为帮助孩子自测和练习&…

Redis到底支不支持事务?

文章目录 一、概述二、使用1、正常执行&#xff1a;2、主动放弃事务3、全部回滚:4、部分支持事务:5、WATCH: 三、事务三阶段四、小结 redis是支持事务的&#xff0c;但是它与传统的关系型数据库中的事务是有所不同的 一、概述 概念: 可以一次执行多个命令&#xff0c;本质是一…

STM32项目分享:智能家居安防系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 2.PCB板及元器件图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片&#xff1a; 哔哩哔哩视频链接&#xff1a; https://www.bilibili.c…

【数据分析基础】实验numpy、pandas和matplolib

文件score.xlsx 中存放了学生的各个科目的考试成绩&#xff08;如下图&#xff09;&#xff0c; 1. 编程实现&#xff1a;输入任意一个学号&#xff0c;将该学号对应的成绩&#xff0c;通过雷达图显示。 &#xff08;1&#xff09;程序代码&#xff1a; import pandas as pd…

9.1 Go 接口的定义

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

JavaScript 动态网页实例 —— 图像显示

图像是网页设计中必不可少的内容之一,而图像的显示方式更是关系到网站的第一印象。本章介绍图像的显示,主要包括:图片的随机显示、图像的显示和隐藏、图像的滚动显示、图像的探照灯扫描显示、多幅图像的翻页显示、图像的水纹效果显示、全景图效果显示手电照射效果显示以及雷达…

16_ Vue.js高级指南:条件渲染、列表渲染与数据双向绑定

文章目录 1. 条件渲染v-if2. 列表渲染v-for3. 数据双项绑定v-model4. 计算属性Appendix 1. 条件渲染v-if v-if标签直接接收函数或boolean类型变量 v-if 为true&#xff0c;则当前元素会进入到dom树v-else会自动执行 前方v-if的取反操作 v-show v-show值为true则值展示值不展示…

【Python】解决Python报错:TypeError: ‘int‘ object is not callable

​​​​ 文章目录 引言1. 错误详解2. 常见的出错场景2.1 误用变量名2.2 混淆函数与结果 3. 解决方案3.1 明确变量类型3.2 使用函数调用() 4. 预防措施4.1 代码审查4.2 单元测试 结语 引言 在Python开发中&#xff0c;TypeError 是一种常见的错误类型&#xff0c;尤其是在尝试…

kafka-重试和死信主题(SpringBoot整合Kafka)

文章目录 1、重试和死信主题2、死信队列3、代码演示3.1、appication.yml3.2、引入spring-kafka依赖3.3、创建SpringBoot启动类3.4、创建生产者发送消息3.5、创建消费者消费消息 1、重试和死信主题 kafka默认支持重试和死信主题 重试主题&#xff1a;当消费者消费消息异常时&…

C++基础7:STL六大组件

目录 一、标准容器 1、顺序容器 vector ​编辑 deque list 容器适配器 stack queue prority_queue: 关联容器 有序关联容器set、mutiset、map、mutimap 增删查O(log n) 无序关联容 unordered_set、unordered_mutiset、unordered_map、unordered_mutimap 增删…

C语言实现map数据结构 key—value对应

1.首先43行 createKeyValuePair(char*key ,int value)这个函数就是给一个keyValuePair *pair的指针来通过内存分配将数据key和value存入这个pair指针所对应的内存空间 2.52行freeKeyValuePair这个函数是释放内存空间 3.头文件 struct结构体KeyValuePair就是一个指针一个值 4…