【SpringBoot】SpringBoot集成ElasticSearch

news2024/11/18 0:35:09

文章目录

  • 第一步,导入jar包,注意这里的jar包版本可能和你导入的不一致,所以需要修改
  • 第二步,编写配置类
  • 第三步,填写yml
  • 第四步,编写util类
  • 第五步,编写controller类
  • 第六步,测试即可

第一步,导入jar包,注意这里的jar包版本可能和你导入的不一致,所以需要修改

<properties>
<properties>
    <java.version>1.8</java.version>
    <elasticsearch.version>7.6.2</elasticsearch.version>
</properties>
<!-- elasticsearch -->
<!--es客户端-->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.6.2</version>
</dependency>

<!--springboot的elasticsearch服务-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

第二步,编写配置类

这段代码是一个基本的 Elasticsearch Java 客户端的配置类,用于创建一个 RestHighLevelClient 实例。

其中 RestHighLevelClient 是 Elasticsearch Java 客户端的高级别别名,是基于 LowLevelClient 之上的封装,提供了一些更加方便的方法和功能。

在这段代码中,使用了 @Value 注解来注入三个配置项,包括 hostname,port 和 scheme。这三个配置项分别表示 Elasticsearch 服务器的主机名或 IP 地址,端口号和通信协议。然后使用RestClient.builder() 方法来创建一个 RestClient 实例,传入 Elasticsearch 服务器的地址和端口号,最后将 RestClient 实例传入 RestHighLevelClient 的构造函数中,即可创建一个 RestHighLevelClient 实例。

需要注意的是,这段代码中的 RestHighLevelClient 实例是一个单例对象,只需要在应用程序启动时创建一次即可,因此这个类应该被配置为一个 Spring Bean,以便在需要时注入到其他类中使用。

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ElasticSearchClientConfig {

    @Value("${elasticSearch.hostname}")
    private String hostname;

    @Value("${elasticSearch.port}")
    private Integer port;

    @Value("${elasticSearch.scheme}")
    private String scheme;

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        return new RestHighLevelClient(
                RestClient.builder(new HttpHost(hostname,port,scheme))
        );
    }
}

第三步,填写yml

elasticSearch:
  hostname: 127.0.0.1
  port: 9200
  scheme: http

第四步,编写util类

这是一个Java类,实现了Elasticsearch API的一些基本功能。它定义了创建、检查是否存在、删除索引、添加、修改和删除文档以及搜索文档的方法。该类使用Elasticsearch API的RESTful客户端来执行这些操作。

以下是每种方法的概述:

  • createIndex(字符串索引):使用给定的名称创建一个索引。
  • existIndex(字符串索引):检查是否存在具有给定名称的索引。
  • deleteIndex(字符串索引):删除具有给定名称的索引。
  • addDocument(动态动态,字符串索引):使用给定的名称将文档添加到索引中。
  • existDocument(字符串索引,字符串文档):检查具有给定ID的文档是否存在于具有给定名称的索引中。
  • getDocument(字符串索引,字符串文档):从具有给定名称的索引中检索具有给定ID的文档。
  • updateDocument(动态动态、字符串索引、字符串文档):在具有给定名称的索引中更新具有给定ID的文档。
  • deleteDocument(字符串索引,字符串文档):从具有给定名称的索引中删除具有给定ID的文档。
  • bulkAddDocument(List<Dynamic>dynamics):在一个批次中将多个具有给定名称的文档添加到索引中。
  • searchDocument(字符串索引):根据搜索查询在索引中搜索具有给定名称的文档。
import com.alibaba.fastjson.JSON;
import com.wangfugui.apprentice.dao.domain.Dynamic;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @since JDK 1.8.0
 */
@Component
@Slf4j
public class ElasticSearchUtil {

    @Autowired
    @Qualifier("restHighLevelClient")
    private RestHighLevelClient client;

    //索引的创建
    public CreateIndexResponse createIndex(String index) throws IOException {
        //1.创建索引的请求
        CreateIndexRequest request = new CreateIndexRequest(index);
        //2客户端执行请求,请求后获得响应
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        log.info("索引的创建{}", response);
        return response;
    }

    //索引是否存在
    public Boolean existIndex(String index) throws IOException {
        //1.创建索引的请求
        GetIndexRequest request = new GetIndexRequest(index);
        //2客户端执行请求,请求后获得响应
        boolean exist = client.indices().exists(request, RequestOptions.DEFAULT);
        log.info("索引是否存在-----" + exist);
        return exist;
    }

    //删除索引
    public Boolean deleteIndex(String index) throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest(index);
        AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
        log.info("删除索引--------" + delete.isAcknowledged());
        return delete.isAcknowledged();
    }

    //添加文档
    public IndexResponse addDocument(Dynamic dynamic, String index) throws IOException {
        IndexRequest request = new IndexRequest(index);
        //设置超时时间
        request.timeout("1s");
        //将数据放到json字符串
        request.source(JSON.toJSONString(dynamic), XContentType.JSON);
        //发送请求
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        log.info("添加文档-------" + response.toString());
        log.info("添加文档-------" + response.status());
        return response;
    }

    //文档是否存在
    public Boolean existDocument(String index, String documents) throws IOException {
        //文档的 没有index
        GetRequest request = new GetRequest(index, documents);
        //没有indices()了
        boolean exist = client.exists(request, RequestOptions.DEFAULT);
        log.info("文档是否存在-----" + exist);
        return exist;
    }

    //获取文档
    public GetResponse getDocument(String index, String documents) throws IOException {
        GetRequest request = new GetRequest(index, documents);
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        log.info("获取文档-----" + response.getSourceAsString());
        log.info("获取文档-----" + response);
        return response;
    }

    //修改文档
    public UpdateResponse updateDocument(Dynamic dynamic, String index, String documents) throws IOException {

        //修改是id为1的
        UpdateRequest request = new UpdateRequest(index, documents);
        request.timeout("1s");
        request.doc(JSON.toJSONString(dynamic), XContentType.JSON);

        UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
        log.info("修改文档-----" + response);
        log.info("修改文档-----" + response.status());

        return response;
    }


    //删除文档
    public RestStatus deleteDocument(String index, String documents) throws IOException {
        DeleteRequest request = new DeleteRequest(index, documents);
        request.timeout("1s");
        DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
        log.info("删除文档------" + response.status());
        return response.status();
    }

    //批量添加文档
    public BulkResponse bulkAddDocument(List<Dynamic> dynamics) throws IOException {

        //批量操作的Request
        BulkRequest request = new BulkRequest();
        request.timeout("1s");

        //批量处理请求
        for (int i = 0; i < dynamics.size(); i++) {
            request.add(
                    new IndexRequest("lisen_index")
                            .id("" + (i + 1))
                            .source(JSON.toJSONString(dynamics.get(i)), XContentType.JSON)
            );
        }
        BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
        //response.hasFailures()是否是失败的
        log.info("批量添加文档-----" + response.hasFailures());

//        结果:false为成功 true为失败
        return response;
    }


    //查询文档
    public SearchResponse searchDocument(String index) throws IOException {
        SearchRequest request = new SearchRequest(index);
        //构建搜索条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //设置了高亮
        sourceBuilder.highlighter();
        //term name为cyx1的
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "cyx1");
        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        request.source(sourceBuilder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        log.info("查询文档-----" + JSON.toJSONString(response.getHits()));
        log.info("=====================");
        for (SearchHit documentFields : response.getHits().getHits()) {
            log.info("查询文档--遍历参数--" + documentFields.getSourceAsMap());
        }
        return response;
    }

    public IndexResponse addDocumentId(Dynamic dynamic, String index, String id) throws IOException {
        IndexRequest request = new IndexRequest(index);
        //设置超时时间
        request.id(id);
        //将数据放到json字符串
        request.source(JSON.toJSONString(dynamic), XContentType.JSON);
        //发送请求
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        log.info("添加文档-------" + response.toString());
        log.info("添加文档-------" + response.status());
        return response;
    }
}

第五步,编写controller类

这是一个Java类,实现了Elasticsearch API的一些基本功能。它定义了用于创建、检查存在性、删除索引、添加、修改和删除文档,以及搜索文档的方法。该类使用Elasticsearch API的RESTful客户端执行这些操作。

以下是每个方法的概述:

  • createIndex(String index) 创建索引的方法。
  • existIndex(String index) 检查给定名称的索引是否存在的方法。
  • deleteIndex(String index) 删除给定名称的索引的方法。
  • addDocument(Dynamic dynamic, String index) 将文档添加到给定名称的索引的方法。
  • existDocument(String index, String documents) 检查给定名称的索引中是否存在具有给定ID的文档的方法。
  • getDocument(String index, String documents) 从给定名称的索引中检索具有给定ID的文档的方法。
  • updateDocument(Dynamic dynamic, String index, String documents) 在给定名称的索引中更新具有给定ID的文档的方法。
  • deleteDocument(String index, String documents) 从给定名称的索引中删除具有给定ID的文档的方法。
  • bulkAddDocument(List dynamics) 在单个批处理中将多个文档添加到给定名称的索引的方法。
  • searchDocument(String index) 基于搜索查询在给定名称的索引中搜索文档的方法。
import com.wangfugui.apprentice.common.util.ElasticSearchUtil;
import com.wangfugui.apprentice.common.util.ResponseUtils;
import com.wangfugui.apprentice.dao.domain.Dynamic;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.List;

/**
 * @since JDK 1.8.0
 */
@RestController
@RequestMapping("/elasticSearch")
@Api(tags = "elasticSearch操作")
public class ElasticSearchController {

    @Autowired
    private ElasticSearchUtil elasticSearchUtil;

    /**索引的创建*/
    @PostMapping("/createIndex")
    @ApiOperation("索引的创建")
    public ResponseUtils createIndex(@RequestParam String index) throws IOException {
        return ResponseUtils.success(elasticSearchUtil.createIndex(index));
    }

    /**索引是否存在*/
    @GetMapping("/existIndex")
    @ApiOperation("索引是否存在")
    public ResponseUtils existIndex(@RequestParam String index) throws IOException {
        return ResponseUtils.success(elasticSearchUtil.existIndex(index));
    }

    /**删除索引*/
    @DeleteMapping("/deleteIndex")
    @ApiOperation("删除索引")
    public ResponseUtils deleteIndex(@RequestParam String index) throws IOException {
        return ResponseUtils.success(elasticSearchUtil.deleteIndex(index));
    }

    /**添加文档*/
    @PostMapping("/addDocument")
    @ApiOperation("添加文档随机id")
    public ResponseUtils addDocument(@RequestBody Dynamic dynamic, @RequestParam String index) throws IOException {
        return ResponseUtils.success(elasticSearchUtil.addDocument(dynamic,index));
    }

    /**添加文档*/
    @PostMapping("/addDocument")
    @ApiOperation("添加文档自定义id")
    public ResponseUtils addDocumentId(@RequestBody Dynamic dynamic, @RequestParam String index,@RequestParam String id) throws IOException {
        return ResponseUtils.success(elasticSearchUtil.addDocumentId(dynamic,index,id));
    }

    /**文档是否存在*/
    @GetMapping("/existDocument")
    @ApiOperation("文档是否存在")
    public ResponseUtils existDocument(@RequestParam String index, @RequestParam String documents) throws IOException {
        return ResponseUtils.success(elasticSearchUtil.existDocument(index,documents));
    }

    /**获取文档*/
    @GetMapping("/getDocument")
    @ApiOperation("获取文档")
    public ResponseUtils getDocument(@RequestParam String index, @RequestParam String documents) throws IOException {
        return ResponseUtils.success(elasticSearchUtil.getDocument(index,documents));
    }

    /**修改文档*/
    @ApiOperation("修改文档")
    @PutMapping("/updateDocument")
    public ResponseUtils updateDocument(@RequestBody Dynamic dynamic, @RequestParam String index, @RequestParam String documents) throws IOException {

        return ResponseUtils.success(elasticSearchUtil.updateDocument(dynamic,index,documents));
    }


    /**删除文档*/
    @ApiOperation("删除文档")
    @DeleteMapping("/deleteDocument")
    public ResponseUtils deleteDocument(@RequestParam String index, @RequestParam String documents) throws IOException {
        return ResponseUtils.success(elasticSearchUtil.deleteDocument(index,documents));
    }

    /**批量添加文档*/
    @ApiOperation("批量添加文档")
    @PostMapping("/bulkAddDocument")
    public ResponseUtils bulkAddDocument(@RequestBody List<Dynamic> dynamics) throws IOException {

        return ResponseUtils.success(elasticSearchUtil.bulkAddDocument(dynamics));
    }


    /**查询文档*/
    @ApiOperation("查询文档")
    @GetMapping("/searchDocument")
    public ResponseUtils searchDocument(@RequestParam String index) throws IOException {
        return ResponseUtils.success(elasticSearchUtil.searchDocument(index));
    }


}

第六步,测试即可

在这里插入图片描述

成功!!

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

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

相关文章

黎曼几何与黎曼流形

目录 0.黎曼几何 1. 欧几里得几何与黎曼几何的区别 2.黎曼流形 3.黎曼距离 4.切空间 5.黎曼均值 6. SPD矩阵如何形成黎曼流型 7.切线空间映射 8.同余变换和同余不变 9.黎曼对齐 科普性笔记&#xff0c;做了解&#xff0c;不深入。 0.黎曼几何 黎曼几何是一种基于欧几…

MySQL 表操作

目录 创建表 案例 查看表结构 修改表 案例&#xff1a; 删除表 创建表 CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎 ; 说明&#xff1a; field 表示列名 dat…

【Vue学习笔记3】使用Vite开启一个Vue3工程项目

1. 什么是Vite? Vite是一个web开发构建工具。Vite 的竞品是 Webpack&#xff0c;而且按照现在的趋势看&#xff0c;使用率超过 Webpack 也是早晚的事。 Vite 主要提升的是开发的体验&#xff0c;Webpack启动调试环境需要 3 分钟都很常见&#xff0c;Vite大大缩短了这个时间。…

应急加固初试(windows sever 2008)

前言 红中(hong_zh0) CSDN内容合伙人、2023年新星计划web安全方向导师、 华为MindSpore截至目前最年轻的优秀开发者、IK&N战队队长、 吉林师范大学网安大一的一名普通学生、搞网安论文拿了回大挑校二、 阿里云专家博主、华为网络安全云享专家、腾讯云自媒体分享计划博主 …

SEO优化新手必须掌握的10个技巧和工具

随着互联网的不断发展&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;已成为网站拓展和推广的重要手段之一。对于新手而言&#xff0c;学习SEO的基础知识和技巧是至关重要的。在本文中&#xff0c;我将分享SEO优化新手必须掌握的10个技巧和工具。 1.关键词研究 关键词是…

Spring Cloud学习笔记【分布式配置中心-Config】

文章目录 SpringCloud Config概述概述传统方式弊端主要功能与GitHub整合配置 Config服务端配置与测试服务端配置(即Gitee上的配置文件)Config Demo配置Spring Cloud Config访问规则 Config客户端配置与测试bootstrap.yml说明Config客户端 Demo配置 SpringCloud Config概述 概述…

学校信息化管理系统通常包含哪些功能?

学校管理信息化是现代教育发展的必然趋势&#xff0c;随着信息技术的飞速发展&#xff0c;学校管理也逐渐地实现了信息化。信息化的学校管理已经成为教育现代化建设的重要内容&#xff0c;也是提高学校教育教学质量和保障学生安全的重要手段。 作为一款低代码开发平台&#xf…

【Shell编程】| if 判断的五个关键点

个人主页&#xff1a;董哥聊技术 我是董哥&#xff0c;嵌入式领域新星创作者 创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01; 文章目录 1、if语法格式1.1 if格式1.2 else if 和 else 2、算数比较3、文件判断4、字符串判断5、test指令测试…

Unity Audio -- (1)概览

准备工作 资源包&#xff1a; https://connect-prd-cdn.unity.com/20230208/8dab3a98-4fe1-4adf-99df-8f6c9e1058c9/creativecore-audio-2021.3LTS.zip 下载&#xff0c;解压后用Unity Hub导入本地工程&#xff0c;具体方法&#xff0c;参考&#xff1a; Project setup proce…

放弃40k月薪的程序员工作,选择公务员,我来分享一下看法

我有一个朋友&#xff0c;拒绝了我为他提供的4万薪水的工作&#xff0c;去了一个体制内的银行&#xff0c;做程序员&#xff0c;即使薪水减半。他之前在北京一家大公司做程序员&#xff0c;一个月30k。当我开始创业时&#xff0c;我拉他来和我一起干&#xff0c;但那时我们太小…

干货 | 思维转变之如何成为一个快速学习者!!!

Hello&#xff0c;大家好&#xff01; 这里是壹脑云科研圈&#xff0c;我是喵君姐姐&#xff5e; 在信息爆炸的今天&#xff0c;网络上有各种资源&#xff0c;其实有心想要学习&#xff0c;都可以学到。 但是&#xff0c;其实自我学习的过程还是比较艰难&#xff0c;那么是否…

人员管理KPI和OKR

文章目录 人员管理KPI和PI一、关键绩效指标概述&#xff08;一&#xff09;关键绩效指标的内涵&#xff08;二&#xff09;关键绩效指标的类型&#xff08;三&#xff09;基于关键绩效指标的绩效指标体系 二、关键绩效指标库三、指标权重与员工责任 OKR360 环评3P汇报法 人员管…

只使用位运算实现加减乘除

在线OJ: LeetCode 29. 两数相除 原题目的要求是不能使用乘法, 除法和取余运算符实现除法. 在本篇博客中把题目要求提高一点, 这里只使用位运算来实现, 顺便的也就把只使用位运算实现加减乘除实现了. 1 . 实现加法 首先我们需要知道两数之和可以是两个数位相加和不进位相加之…

c++ 入门概述

c 入门概述 1. c 关键字2. c 命名空间3. c 输入与输出4. c 缺省参数5. c 函数重载6. c 引用6.1 引用概念6.2 引用特性6.3 常引用6.4 引用与指针区别 7. c 内联函数8. c auto 关键字9. 范围 for 循环 1. c 关键字 c 98中&#xff0c;规定的关键字总共有63个&#xff1a; 2. c…

排序算法 - 插入排序

文章目录 插入排序介绍插入排序实现插入排序的时间复杂度和稳定性插入排序时间复杂度插入排序稳定性 代码实现核心&总结 每日一道算法&#xff0c;提高脑力。第三天&#xff0c;插入排序。 插入排序介绍 插入排序(Insertion Sort)的基本思想是: 把n个待排序的元素看成为一…

全网最火,Web自动化测试驱动模型详全,一语点通超实用...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 自动化测试模型&a…

我记不住的那些Git的操作

背景&#xff1a;其实接触Git也很长时间了&#xff0c;自打上学那会就用Git作为版本控制工具&#xff0c;感触颇深。写这篇文章也是记录一下自己的理解留作日后词典进行查询&#xff0c;另外也是想把这些内容分享给大家。本篇将以问题为导向来阐述相关的知识&#xff0c;面对的…

mid360激光雷达跑Point-LIO算法

在商场里面上下楼穿梭,使用mid360激光雷达,完成建图 以下是建图的运行过程及参数配置 mid360激光雷达驱动 安装(ubuntu20.4 ) /ws_livox/src/livox_ros_driver2$source /opt/ros/noetic/setup.sh /ws_livox/src/livox_ros_driver2$./build.sh ROS1配置修改MID360_confi…

《花雕学AI》06:ChatGPT,一种新型的对话生成模型的机遇、挑战与评估

最近ChatGPT持续大火&#xff0c;大家们是不是在网上看到各种和ChatGPT有趣聊天的截图&#xff0c;奈何自己实力不够&#xff0c;被网络拒之门外&#xff0c;只能眼馋别人的东西。看别人在体验&#xff0c;看别人玩&#xff0c;肯定不如自己玩一把舒服的啊。 上一期&#xff0…

( “图“ 之 二分图 ) 785. 判断二分图 ——【Leetcode每日一题】

❓785. 判断二分图 难度&#xff1a;中等 存在一个 无向图 &#xff0c;图中有 n 个节点。其中每个节点都有一个介于 0 到 n - 1 之间的唯一编号。给你一个二维数组 graph &#xff0c;其中 graph[u] 是一个节点数组&#xff0c;由节点 u 的邻接节点组成。形式上&#xff0c;…