ES 7.6 - JAVA应用基础操作篇

ES 7.6 - JAVA应用基础操作篇

    • 环境准备
      • 依赖配置
    • 实体类准备
    • 使用说明
    • 索引/映射操作
      • 创建索引和映射
      • 索引和映射相关查询
      • 删除索引
    • 文档操作
      • 插入数据
      • 更新数据
      • 删除数据
      • 批量操作
    • 文档查询
      • 根据ID查询
      • 根据字段精准查询
      • 根据字段分词查询
      • 控制返回字段
      • 范围查询
      • 组合查询
      • 排序+分页
      • 高亮搜索
      • 聚合查询
    • 场景查询实操
      • 查询2023年中男、女的数量并找出对应的最大/最小年龄
      • 查询在地址中包含 "深圳" 或者 备注中包含 "积极" 的 男性青年(18-30岁)
      • 要求根据关键字找出匹配项目标,高亮实时预览
      • 分别找出男、女性别中年龄最小的三个人(TOP N)
      • 查询tag中带有某些标签的或者出身地在某某地的人,按照年龄降序,并且分页
    • 总结

上文已经教了大家最基本的操作了,那我们在java代码里面要如何实现呢?本文的目的就是教大家在springboot框架下实现上文的API操作,也就是CURD!

环境准备

首先我们要知道ES的API都是HTTP请求!!!!,所以什么语言都可以操作,就是发送请求和处理返回而已嘛,只是说现在这种封装不需要我们做,有人做好了,这种叫做ES的客户端!

依赖配置

我们直接采用Spring-data-es的依赖,先看一下版本依赖说明:

在这里插入图片描述

这里建议客户端版本和你自身搭建的es版本保持一致(es不同版本间api差异很大,如果不想出现莫名其妙的错的最好一致),所以这里我们选择springboot 2.3版本,这里给出spring-data-es的官方文档

# springboot版本
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.2.RELEASE</version><relativePath/> <!-- lookup parent from repository -->
</parent># spring-elasticsearch依赖
<dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-elasticsearch</artifactId><version>4.0.9.RELEASE</version>
</dependency>

因为我这ES是7.6的,所以选择使用HighLevelRestClient客户端,虽然这个已经在高版本过时了(8.x),但是在7.x版本里面官方建议使用这个

在这里插入图片描述

项目引入依赖后,使用非常简单,文件中配置一下ES地址,就可以愉快的访问啦:

# yml配置文件
spring:elasticsearch:rest:uris: ip:portusername: password: 

实体类准备

@Data
@Document(indexName = "es_apply_test")
public class EsTest {@Idprivate Long id;@Field(type = FieldType.Text,analyzer = "ik_max_word")private String name;@Field(type = FieldType.Keyword)private String sex;@Field(type = FieldType.Integer)private Integer age;@Field(type = FieldType.Text,analyzer = "ik_max_word")private String remark;@Field(type = FieldType.Keyword)private String[] tag;@Field(type = FieldType.Text,analyzer = "ik_max_word")private String addressLocation;@Field(type = FieldType.Keyword)private String birthAddress;@Field(type = FieldType.Date,pattern = "yyyy-MM-dd HH:mm:ss",format = DateFormat.custom)private Date createTime;@Field(type = FieldType.Boolean)private Boolean hasGirlFriend;public EsTest(){}// 下面都是为了生成测试数据而准备的private final static String[] city=new String[]{"深圳","广州","上海","北京","武汉"};private final static String[] address=new String[]{"北京市朝阳区北辰东路15号","上海市黄浦区人民大道200号","深圳市福田区福中三路市民中心C区","武汉市江岸区一元街道沿江大道188号","广州市花都区新华街新都大道68号"};public static EsTest getRandomData(Long id){EsTest esTest = new EsTest();esTest.setId(id);esTest.setName(RandomUtil.randomString("张三李四王五陈六江文档词测试",3));esTest.setSex(id%2==0 ? "男":"女");esTest.setAge(RandomUtil.randomInt(15,30));esTest.setRemark(RandomUtil.randomString("活波开朗,具有进取精神和团队精神,有较强的动手能力。良好协调沟通能力,适应力强,反应快、积极、细心、灵活, 具有一定的社会交往能力",15));esTest.setTag(new String[]{RandomUtil.randomString("活波开朗,具有进取精神和团队精神,有较强的动手能力。良好协调沟通能力,适应力强,反应快、积极、细心、灵活, 具有一定的社会交往能力",3),RandomUtil.randomString("活波开朗,具有进取精神和团队精神,有较强的动手能力。良好协调沟通能力,适应力强,反应快、积极、细心、灵活, 具有一定的社会交往能力",3),RandomUtil.randomString("活波开朗,具有进取精神和团队精神,有较强的动手能力。良好协调沟通能力,适应力强,反应快、积极、细心、灵活, 具有一定的社会交往能力",3)});esTest.setAddressLocation(address[RandomUtil.randomInt(0,address.length-1)]);esTest.setBirthAddress(city[RandomUtil.randomInt(0,city.length-1)]);esTest.setCreateTime(RandomUtil.randomDay(0,100));esTest.setHasGirlFriend(id%4==0 ? true:false);return esTest;}}
  • 注解:@Document用来声明Java对象与ElasticSearch索引的关系

    indexName 索引名称

    type 索引类型

    shards 主分区数量

    replicas 副本分区数量

    createIndex 索引不存在时,是否自动创建索引,默认true

    不建议自动创建索引(自动创建的索引 是按着默认类型和默认分词器)

  • 注解:@Id 表示索引的主键

  • 注解:@Field 用来描述字段的ES数据类型,是否分词等配置,等于Mapping描述

    index 设置字段是否索引,默认是true,如果是false则该字段不能被查询

    store 默认为no,被store标记的fields被存储在和index不同的fragment中,以便于快速检索。虽然store占用磁盘空间,但是减少了计算。

    type 数据类型(text、keyword、date、object、geo等)

    analyzer 对字段使用分词器,注意一般如果要使用分词器,字段的type一般是text。

    format 定义日期时间格式,详细见 官方文档: https://www.elastic.co/guide/reference/mapping/date-format/.

  • 注解:@CompletionField 定义关键词索引 要完成补全搜索

    analyzer 对字段使用分词器,注意一般如果要使用分词器,字段的type一般是text。

    searchAnalyzer 显示指定搜索时分词器,默认是和索引是同一个,保证分词的一致性。

    maxInputLength:设置单个输入的长度,默认为50 UTF-16 代码点

使用说明

我们引入依赖后,在使用的时候有四种使用方式(下面我由简→难说明一下):

  • ElasticsearchRepository:自动生成简单CURD方法,直接调用即可(复杂的不友好)
  • ElasticsearchRestTemplate:内部使用的是RestHighLevelClient,它帮我们封装了一层
  • RestHighLevelClient:直接使用客户端
  • 自己封装客户端:之前说了本质就是HTTP请求,自己封装一下,直接调API呗,这比啥都好使

本文使用ElasticsearchRestTemplate(对小白友好),但是我个人强烈推荐直接用RestHighLevelClient,因为这个支持得更全面还同时支持同步和异步操作,本文有些操作也会用到这个

本文索引名称:es_apply_test

客户端注入:

在这里插入图片描述

索引/映射操作

创建索引和映射

@Test
void createIndexAndMapping() {IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(EsTest.class);// 判断索引是否已经存在if(!indexOperations.exists()){// 不存在则创建indexOperations.create();Document mapping = indexOperations.createMapping(EsTest.class);indexOperations.putMapping(mapping);}log.info("使用API查询查看..................");
}

索引和映射相关查询

@Test
void queryIndexAndMapping() {IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(EsTest.class);boolean exists = indexOperations.exists();log.info("索引是否存在:{}",exists);Map<String, Object> mapping = indexOperations.getMapping();log.info("映射:{}",JSONObject.toJSONString(mapping));Map<String, Object> settings = indexOperations.getSettings();log.info("索引设置:{}",JSONObject.toJSONString(settings));// 索引刷新(这个功能用处,后面讲理论的时候你会知道是干嘛的)indexOperations.refresh();
}

删除索引

@Test
void deletedIndex() {IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(EsTest.class);indexOperations.delete();
}

文档操作

插入数据

/** 插入一条数据 */@Testvoid insertDoc() {// 插入一条elasticsearchRestTemplate.save(EsTest.getRandomData(1L));// 同时插入多条 实际是遍历一条一条插入而不是用的bulk命令elasticsearchRestTemplate.save(EsTest.getRandomData(2L),EsTest.getRandomData(3L));}

更新数据

    /** 更新数据 */@Testvoid updateDoc() throws IOException {// es的数据结构都是文档,其实不存在文档更新,每次更新都会产生新的文档(这个是很低效的),所以es在API方面也看的出来对更新不是很友好// 没办法,虽然更新很低效,但终究得改呀// 下面提供几种方式// 1.根据ID更新UpdateQuery build = UpdateQuery.builder("1").withDocument(Document.parse("{ \"name\": \"根据ID更新\" }")).build();elasticsearchRestTemplate.update(build,elasticsearchRestTemplate.getIndexCoordinatesFor(EsTest.class));// 2.条件更新// 采用highLevel客户端,根据查询条件 使用脚本更新 等同于_update_by_query APIUpdateByQueryRequest request = new UpdateByQueryRequest("es_apply_test");request.setQuery(QueryBuilders.termQuery("age","24"));request.setScript(new Script("ctx._source['age']='300';ctx._source['remark']='根据条件批量更新';"));restHighLevelClient.updateByQuery(request, RequestOptions.DEFAULT);}

删除数据

    /** 删除数据 */@Testvoid deleteDoc() throws IOException {// 1.根据ID删除elasticsearchRestTemplate.delete("1",EsTest.class);// 2.条件删除NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(QueryBuilders.termQuery("id", "3")).build();elasticsearchRestTemplate.delete(build,EsTest.class,elasticsearchRestTemplate.getIndexCoordinatesFor(EsTest.class));}

批量操作

    /** 批量增、删、改操作 */@Testvoid bulkDoc() throws IOException {// 量大的话强烈推荐这种方式,因为ES本身是以查询突出,修改的吞吐量并不高// 1. 批量插入BulkRequest insertRequest = new BulkRequest();for(int i=1;i<=20;i++){IndexRequest indexRequest = new IndexRequest("es_apply_test");indexRequest.id(String.valueOf(i));indexRequest.source(JSONObject.toJSONString(EsTest.getRandomData((long)i)),XContentType.JSON);insertRequest.add(indexRequest);}BulkResponse insertResult = restHighLevelClient.bulk(insertRequest, RequestOptions.DEFAULT);log.info("是否失败: {},失败原因:{}",insertResult.hasFailures(),insertResult.buildFailureMessage());// 2. 批量更新BulkRequest updateRequest = new BulkRequest();for(int i=1;i<=5;i++){UpdateRequest indexRequest = new UpdateRequest();indexRequest.id(String.valueOf(i));indexRequest.index("es_apply_test");HashMap<String, Object> objectObjectHashMap = new HashMap<>();objectObjectHashMap.put("name","bulk批量更新");indexRequest.doc(objectObjectHashMap);updateRequest.add(indexRequest);}BulkResponse updateResult = restHighLevelClient.bulk(updateRequest, RequestOptions.DEFAULT);log.info("是否失败: {},失败原因:{}",updateResult.hasFailures(),updateResult.buildFailureMessage());// 3. 批量删除BulkRequest deleteRequest = new BulkRequest();for(int i=1;i<=5;i++){DeleteRequest request = new DeleteRequest();request.id(String.valueOf(i));request.index("es_apply_test");updateRequest.add(request);}BulkResponse deleteResult = restHighLevelClient.bulk(deleteRequest, RequestOptions.DEFAULT);log.info("是否失败: {},失败原因:{}",deleteResult.hasFailures(),deleteResult.buildFailureMessage());// 当然也可混合操作 就是 _bulk API}

文档查询

根据ID查询

    /** 根据id查 */@Testvoid getDataById() {EsTest esTest = elasticsearchRestTemplate.get("1", EsTest.class);log.info("结果:{}", JSONObject.toJSONString(esTest));}

根据字段精准查询

    @Testvoid termQuery() {// term 精准查询TermQueryBuilder termQuery = QueryBuilders.termQuery("age", 10);NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(termQuery);SearchHits<EsTest> termResult = elasticsearchRestTemplate.search(nativeSearchQuery, EsTest.class);log.info("term-> 总数量:{} 结果:{}", termResult.getTotalHits(),JSONObject.toJSONString(termResult.getSearchHits()));// terms 精准查询TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("tag", "良心力", "高于动");NativeSearchQuery nativeSearchQuery1 = new NativeSearchQuery(termsQueryBuilder);SearchHits<EsTest> termsResult = elasticsearchRestTemplate.search(nativeSearchQuery1, EsTest.class);log.info("terms-> 总数量:{} 结果:{}", termsResult.getTotalHits(),JSONObject.toJSONString(termsResult.getSearchHits()));}

根据字段分词查询

    /** 根据字段分词查询 */@Testvoid matchQuery() {// matchall 全量查询 默认是分页查询10条MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(matchAllQueryBuilder);SearchHits<EsTest> matchAll = elasticsearchRestTemplate.search(nativeSearchQuery, EsTest.class);log.info("match all-> 总数量:{} 结果:{}", matchAll.getTotalHits(),JSONObject.toJSONString(matchAll.getSearchHits()));// match 根据字段分词查询(字段分词)MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("addressLocation", "街道");NativeSearchQuery nativeSearchQuery1 = new NativeSearchQuery(matchQueryBuilder);SearchHits<EsTest> match = elasticsearchRestTemplate.search(nativeSearchQuery1, EsTest.class);log.info("match -> 总数量:{} 结果:{}", match.getTotalHits(),JSONObject.toJSONString(match.getSearchHits()));// match_phrase 根据字段分词查询(字段不分词)MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("addressLocation", "街道,武汉");NativeSearchQuery nativeSearchQuery2 = new NativeSearchQuery(matchPhraseQueryBuilder);SearchHits<EsTest> matchPhrase = elasticsearchRestTemplate.search(nativeSearchQuery2, EsTest.class);log.info("match_phrase -> 总数量:{} 结果:{}", matchPhrase.getTotalHits(),JSONObject.toJSONString(matchPhrase.getSearchHits()));// multi_match 根据字段分词查询多个字段MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("街道,武汉,队协", "addressLocation", "remark");NativeSearchQuery nativeSearchQuery3 = new NativeSearchQuery(multiMatchQueryBuilder);SearchHits<EsTest> multiMatch = elasticsearchRestTemplate.search(nativeSearchQuery3, EsTest.class);log.info("multiMatch -> 总数量:{} 结果:{}", multiMatch.getTotalHits(),JSONObject.toJSONString(multiMatch.getSearchHits()));}

控制返回字段

    /** 控制返回字段 */@Testvoid fieldFilterQuery() {// matchall 全量查询 并控制返回字段NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchAllQuery()).withFields("id", "name").build();SearchHits<EsTest> matchAll = elasticsearchRestTemplate.search(build, EsTest.class);log.info("match all-> 总数量:{} 结果:{}", matchAll.getTotalHits(),JSONObject.toJSONString(matchAll.getSearchHits()));}

范围查询

    /** 范围查询 */@Testvoid rangeQuery() {// 范围查询 并控制返回字段NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(QueryBuilders.rangeQuery("age").gte(20).lte(30)).withFields("id", "name","age").build();SearchHits<EsTest> matchAll = elasticsearchRestTemplate.search(build, EsTest.class);log.info("match all-> 总数量:{} 结果:{}", matchAll.getTotalHits(),JSONObject.toJSONString(matchAll.getSearchHits()));}

组合查询

    /** 组合查询 and 、or 、!= */@Testvoid boolGroupQuery() {// 范围查询 并控制返回字段// =10岁 !=男NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("age",23)).mustNot(QueryBuilders.termQuery("sex","男"))).withFields("id", "name","age","sex").build();SearchHits<EsTest> matchAll = elasticsearchRestTemplate.search(build, EsTest.class);log.info("match all-> 总数量:{} 结果:{}", matchAll.getTotalHits(),JSONObject.toJSONString(matchAll.getSearchHits()));}

排序+分页

    /** 排序+分页 */@Testvoid sortAndPageQuery() {// 排序+分页  排序可以多个NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchAllQuery()).withSort(SortBuilders.fieldSort("age").order(SortOrder.ASC)).withSort(SortBuilders.fieldSort("id").order(SortOrder.DESC)).withSort(SortBuilders.scoreSort()).withFields("id", "name","age","sex").withPageable(PageRequest.of(0,5)).build();SearchHits<EsTest> matchAll = elasticsearchRestTemplate.search(build, EsTest.class);log.info("match all-> 总数量:{} 结果:{}", matchAll.getTotalHits(),JSONObject.toJSONString(matchAll.getSearchHits()));}

高亮搜索

    /** 高亮搜索 */@Testvoid highlightQuery() {// 高亮搜索NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(QueryBuilders.multiMatchQuery("武汉深圳", "addressLocation", "remark")).withFields("id", "name","addressLocation","remark").withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:red'>").postTags("</span>")).withHighlightFields(new HighlightBuilder.Field("addressLocation"),new HighlightBuilder.Field("remark")).build();SearchHits<EsTest> matchAll = elasticsearchRestTemplate.search(build, EsTest.class);log.info("match all-> 总数量:{} 结果:{}", matchAll.getTotalHits(),JSONObject.toJSONString(matchAll.getSearchHits()));}

聚合查询

    /** 聚合查询 */@Testvoid aggregateQuery() {// 不分组 聚合查询NativeSearchQuery build = new NativeSearchQueryBuilder().addAggregation(AggregationBuilders.avg("ageAvg").field("age")).addAggregation(AggregationBuilders.sum("ageSum").field("age")).addAggregation(AggregationBuilders.max("ageMax").field("age")).addAggregation(AggregationBuilders.min("ageMin").field("age")).withPageable(PageRequest.of(0,1)) // 应该设置为0,因为只需要聚合数据,但无赖有校验设置不了.build();SearchHits<EsTest> search = elasticsearchRestTemplate.search(build, EsTest.class);log.info("match all-> 总数量:{} 结果:{}", search.getTotalHits(),JSONObject.toJSONString(search.getAggregations()));// 先分组 在聚合NativeSearchQuery build1 = new NativeSearchQueryBuilder().addAggregation(AggregationBuilders.terms("groupBySex").field("sex").subAggregation(AggregationBuilders.avg("ageAvg").field("age")).subAggregation(AggregationBuilders.sum("ageSum").field("age")).subAggregation(AggregationBuilders.max("ageMax").field("age")).subAggregation(AggregationBuilders.min("ageMin").field("age"))).withPageable(PageRequest.of(0,1)) // 应该设置为0,因为只需要聚合数据,但无赖有校验设置不了.build();SearchHits<EsTest> search1 = elasticsearchRestTemplate.search(build1, EsTest.class);Map<String, Aggregation> map = search1.getAggregations().asMap();Aggregation groupBySex = map.get("groupBySex");log.info("打断点看吧:{}",groupBySex);}

场景查询实操

查询2023年中男、女的数量并找出对应的最大/最小年龄

    /** 查询2023年中男、女的数量并找出对应的最大/最小年龄 */@Testvoid demo1() {NativeSearchQuery build = new NativeSearchQueryBuilder().addAggregation(AggregationBuilders.terms("groupBySex").field("sex").subAggregation(AggregationBuilders.count("count").field("id")).subAggregation(AggregationBuilders.max("maxAge").field("age")).subAggregation(AggregationBuilders.min("minAge").field("age"))).withPageable(PageRequest.of(0,1)).build();SearchHits<EsTest> search = elasticsearchRestTemplate.search(build, EsTest.class);log.info("打断点查看:{}",search.getAggregations());}

查询在地址中包含 “深圳” 或者 备注中包含 “积极” 的 男性青年(18-30岁)

要求关键词高亮

/** 查询在地址中包含 "深圳" 或者 备注中包含 "积极" 的 男性青年(18-30岁),要求关键词高亮 */@Testvoid demo2() {NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("sex","男")).must(QueryBuilders.rangeQuery("age").gte(18).lte(30)).must(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("addressLocation","深圳")).should(QueryBuilders.matchQuery("remark","积极")))).withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:red'>").postTags("</span>")).withHighlightFields(new HighlightBuilder.Field("addressLocation"),new HighlightBuilder.Field("remark")).build();SearchHits<EsTest> search = elasticsearchRestTemplate.search(build, EsTest.class);log.info("总量:{} 数据:{}",search.getTotalHits(),JSONObject.toJSONString(search.getSearchHits()));}

要求根据关键字找出匹配项目标,高亮实时预览

(搜地址、名称,返回 名称+id + 地址)

/** 搜索框:要求根据关键字找出匹配项目标,高亮实时预览(搜地址、名称,返回 名称+id + 地址) */@Testvoid demo3() {NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(QueryBuilders.multiMatchQuery("林深","name","addressLocation")).withFields("id", "name","addressLocation").withHighlightBuilder(new HighlightBuilder().preTags("<span style='color:red'>").postTags("</span>")).withHighlightFields(new HighlightBuilder.Field("addressLocation"),new HighlightBuilder.Field("name")).build();SearchHits<EsTest> search = elasticsearchRestTemplate.search(build, EsTest.class);log.info("总量:{} 数据:{}",search.getTotalHits(),JSONObject.toJSONString(search.getSearchHits()));}

分别找出男、女性别中年龄最小的三个人(TOP N)

    /** 分别找出男、女性别中年龄最小的三个人(TOP N) */@Testvoid demo4() {NativeSearchQuery build = new NativeSearchQueryBuilder().addAggregation(AggregationBuilders.terms("groupBySex").field("sex").subAggregation(AggregationBuilders.topHits("top3").sort("age",SortOrder.ASC).fetchSource(new String[]{"name","sex","age"},null).size(3))).build();SearchHits<EsTest> search = elasticsearchRestTemplate.search(build, EsTest.class);log.info("打断点自己看-》总量:{} 数据:{}",search.getTotalHits(),search.getAggregations());}

查询tag中带有某些标签的或者出身地在某某地的人,按照年龄降序,并且分页

    /** 查询tag中带有某些标签的或者出身地在某某地的人,按照年龄降序,并且分页 */@Testvoid demo5() {NativeSearchQuery build = new NativeSearchQueryBuilder().withQuery(QueryBuilders.boolQuery().should(QueryBuilders.termsQuery("tag","断能能","高于动","上格心","对朗步")).should(QueryBuilders.termsQuery("birthAddress","深圳","章丘"))).withSort(SortBuilders.fieldSort("age").order(SortOrder.DESC)).withSort(SortBuilders.scoreSort().order(SortOrder.DESC)).withPageable(PageRequest.of(0,5)).build();SearchHits<EsTest> search = elasticsearchRestTemplate.search(build, EsTest.class);log.info("总量:{} 数据:{}",search.getTotalHits(),search.getSearchHits());}

总结

到了这恭喜你,你也成功的入门ES,成为了一名ES的CURD BOY,但你觉得ES就仅仅如此吗?少年加油吧,才刚开始呢!!

后面会介绍一些重点操作,以及相应的进阶理论知识,理论会偏多!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图像颜色空间转换

目录 1.图像颜色空间介绍 RGB 颜色空间 2.HSV 颜色空间 3.RGBA 颜色空间 2.图像数据类型间的互相转换convertTo() 3.不同颜色空间互相转换cvtColor() 4.Android JNI demo 1.图像颜色空间介绍 RGB 颜色空间 RGB 颜色空间是最常见的颜色表示方式之一&#xff0c;其中 R、…

【MySql】mysql之基础语句

一、常用的数据类型 类型解释举例int整型用于定义整数类型的数据&#xff08;1、2、3、4、5…&#xff09;float单精度浮点&#xff08;4字节32位&#xff09;准确表示小数点后六位double双精度浮点&#xff08;8字节64位&#xff09;小数位更多&#xff0c;更精确char固定长度…

Go语言基础之指针

区别于C/C中的指针&#xff0c;Go语言中的指针不能进行偏移和运算&#xff0c;是安全指针。 要搞明白Go语言中的指针需要先知道3个概念&#xff1a;指针地址、指针类型和指针取值。 Go语言中的指针 任何程序数据载入内存后&#xff0c;在内存都有他们的地址&#xff0c;这就…

微信小程序使用stomp.js实现STOMP传输协议的实时聊天

简介&#xff1a; uniapp开发的小程序中使用 本来使用websocket&#xff0c;后端同事使用了stomp协议&#xff0c;导致前端也需要对应修改。 如何使用 在static/js中新建stomp.js和websocket.js&#xff0c;然后在需要使用的页面引入监听代码发送代码即可 代码如下&#x…

腾讯云-对象存储服务(COS)的使用总结

简介 对象存储&#xff08;Cloud Object Storage&#xff0c;COS&#xff09;是腾讯云提供的一种存储海量文件的分布式存储服务&#xff0c;具有高扩展性、低成本、可靠安全等优点。通过控制台、API、SDK 和工具等多样化方式&#xff0c;用户可简单、快速地接入 COS&#xff0…

论文笔记:从不平衡数据流中学习的综述: 分类、挑战、实证研究和可重复的实验框架

0 摘要 论文&#xff1a;A survey on learning from imbalanced data streams: taxonomy, challenges, empirical study, and reproducible experimental framework 发表&#xff1a;2023年发表在Machine Learning上。 源代码&#xff1a;https://github.com/canoalberto/imba…

Python Qt(七)Listview

源代码&#xff1a; # -*- coding: utf-8 -*-# Form implementation generated from reading ui file qt_listview.ui # # Created by: PyQt5 UI code generator 5.15.9 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not…

Docker之私有仓库 RegistryHarbor

目录 一、Docker私有仓库&#xff08;Registry&#xff09; 1.1 Registry的介绍 二、搭建本地私有仓库 2.1首先下载 registry 镜像 2.2在 daemon.json 文件中添加私有镜像仓库地址 2.3运行 registry 容器 2.4Docker容器的重启策略 2.5为镜像打标签 2.6上传到私有仓库 2…

jvm的内存区域

JVM 内存分为线程私有区和线程共享区&#xff0c;其中方法区和堆是线程共享区&#xff0c;虚拟机栈、本地方法栈和程序计数器是线程隔离的数据区。 1&#xff09;程序计数器 程序计数器&#xff08;Program Counter Register&#xff09;也被称为 PC 寄存器&#xff0c;是一块…

基于Echarts的大数据可视化模板:大数据医疗服务平台

目录 引言大数据在医疗领域的应用ECharts在医疗服务中的作用医疗大数据的应用方向临床决策支持药物研发与安全性监测健康管理与预防流行病监测与公共卫生基因组学与个性化医疗医疗保险与费用管理Echarts与大数据可视化Echarts库以及其在大数据可视化领域的应用优势开发过程和所…

只考一门数据结构,计算机学硕复录比1:1的山东双非学校考情分析

青岛理工大学 考研难度&#xff08;☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分析&#xff09;、院校概况、23专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文1420字&#xff0c;预计阅读&#xff1a;3分钟 2023考情概况 青岛理工…

redis缓存雪崩、穿透、击穿解决方案

redis缓存雪崩、穿透、击穿解决方案 背景缓存雪崩缓存击穿缓存穿透总结背景 关于缓存异常,我们常见的有三个问题:缓存雪崩、缓存击穿、缓存穿透。这三个问题一旦发生,会导致大量请求直接落到数据库层面。如果请求的并发量很大,会影响数据库的运行,严重的会导致数据库宕机…

openGauss学习笔记-54 openGauss 高级特性-MOT

文章目录 openGauss学习笔记-54 openGauss 高级特性-MOT54.1 MOT特性及价值54.2 MOT关键技术54.3 MOT应用场景54.4 不支持的数据类型54.5 使用MOT54.6 将磁盘表转换为MOT openGauss学习笔记-54 openGauss 高级特性-MOT openGauss引入了MOT&#xff08;Memory-Optimized Table&…

如何高效地设计测试用例并评审

编写出好的测试用例是每一个测试工程师的职责&#xff0c;但在实际工作中大家写的测试用例往往需要不断地修改才能使用&#xff0c;这不仅浪费了时间&#xff0c;还容易让测试工程师产生自我否定的情绪&#xff0c;甚至在团队中产生各种矛盾。 那如何高效地设计测试用例呢&…

可直接运营的餐饮外卖点餐自提单多门店小程序开发演示

适合鲜花店、蛋糕店、奶茶店、餐饮店、便利店等门店商家的小程序。 小程序系统支持外卖和自提两种模式&#xff0c;帮助商家打造自己的私域流量池&#xff0c;减少对美团和饿了么的依赖&#xff0c;提升用户点餐、就餐体验。 支持会员签到获取积分的功能&#xff0c;积分可用…

jwt安全问题

文章目录 jwt安全问题jwt简介jwt组成headerpayloadsignature 潜在漏洞空加密算法web346 密钥爆破web348 敏感信息泄露web349 **修改算法RS256为HS256**web350 jwt安全问题 jwt简介 JWT的全称是Json Web Token&#xff0c;遵循JSON格式&#xff0c;跨域认证解决方案&#xff0…

【93】PCI Expansion ROM

1、Expansion ROM PCIe、PCI设备可以提供Expansion ROM&#xff0c;Expansion ROM中存在设备初始化或者system boot的code。SystemBIOS在POST&#xff08;Power-on Self Test&#xff09;阶段&#xff0c;会枚举PCI设备&#xff0c;并判断有设备是否支持Expansion ROM&#xff…

Python爬虫武汉市二手房价格数据采集分析:Linear Regression、XGBoost和LightGBM|代码分享...

全文链接&#xff1a;http://tecdat.cn/?p31958 分析师&#xff1a;Yan Liu 我国有大量的资金都流入了房地产行业&#xff0c;同时与其他行业有着千丝万缕的联系&#xff0c;可以说房地产行业对推动我国深化改革、经济发展、工业化和城市化具有不可磨灭的作用&#xff08;点击…

WebSocket详解以及应用

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;websocket、网络、长连接、前端☀️每日 一言&#xff1a;任何一个你不喜欢而又离不开的地方&#xff0c;任何一种你不喜欢而又无法摆脱的生活&#xff0c;都是监狱&#xff01; 一、前言 我们在…

基于Spring Gateway路由判断器实现各种灰度发布场景

文章目录 1、灰度发布实现1.1 按随机用户的流量百分比实现灰度1.2 按人群划分实现的灰度1.2.1 通过Header信息实现灰度1.2.2 通过Query信息实现灰度1.2.3 通过RemoteAdd判断来源IP实现灰度 2、路由判断器2.1. After2.2. Before2.3. Between2.4. Cookie2.5. Header2.6. Host2.7.…