【业务功能篇90】微服务-springcloud-检索服务-ElasticSearch实战运用-DSL语句
商城检索服务
1.检索页面的搭建
商品检索页面我们放在search服务中处理,首页我们需要在mall-search服务中支持Thymeleaf。添加对应的依赖
<!-- 添加Thymeleaf的依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>
然后我们拷贝模板文件到template目录下,然后不要忘记添加Thymeleaf的名称空间
需要把相关的静态资源文件拷贝到Nginx服务中。目录结构是:/mydata/nginx/html/static/search/
我们需要修改index.html页面中的资源的路径
然后我们要通过 msb.search.com
来访问我们的检索服务,那么就需要设置对应的host文件
然后我们就需要修改Nginx的配置
这时我需要在修改网关的服务,根据我们的域名访问,那么需要网关路由到我们的检索服务中
然后我们就可以重启相关的服务 ,来测试了
2.检索服务
2.1 创建对应VO
我们需要检索数据库中的相关的商品信息,那么我们就需要提交相关的检索条件,为了统一的管理提交的数据,我们需要创建一个VO来封装信息。
/*** 封装页面所有可能提交的查询条件*/
@Data
public class SearchParam {private String keyword; // 页面传递的查询全文匹配的关键字private Long catalog3Id;// 需要根据分类查询的编号/*** sort=salaCount_asc/desc* sort=skuPrice_asc/desc* sort=hotScore_asc/desc*/private String sort; // 排序条件// 查询的筛选条件 hasStock=0/1;private Integer hasStock ; // 是否只显示有货// brandId=1&brandId=2private List<Long> brandId; // 按照品牌来查询,可以多选// skuPrice=200_300// skuPrice=_300// skuPrice=200_private String skuPrice; // 价格区间查询// 不同的属性 attrs:1_苹果:6.5寸private List<String> attrs; // 按照属性信息进行筛选private Integer pageNum; // 页码}
然后就是检索后的数据我们需要封装的VO对象,定义如下:
package com.msb.mall.mallsearch.vo;import com.msb.common.dto.es.SkuESModel;
import lombok.Data;import java.util.List;/*** 封装检索后的响应信息*/
@Data
public class SearchResult {private List<SkuESModel> products; // 查询到的所有的商品信息 满足条件// 分页信息private Integer pageNum; // 当前页private Long total; // 总的记录数private Integer totalPages; // 总页数// 当前查询的所有的商品涉及到的所有的品牌信息private List<BrandVO> brands;// 当前查询的所有的商品涉及到的所有的属性信息private List<AttrVo> attrs;// 当前查询的所有商品涉及到的所有的类别信息private List<CatalogVO> catalogs;@Datapublic static class CatalogVO{private Long catalogId;private String catalogName;}/*** 品牌的相关信息*/@Datapublic static class BrandVO{private Long brandId; // 品牌的编号private String brandName; // 品牌的名称private String brandImg; // 品牌的图片}@Datapublic static class AttrVo{private Long attrId; // 属性的编号private String attrName; // 属性的名称private List<String> attrValue; // 属性的值}}
2.2 构建查询DSL语句
我们需要根据基本的检索条件来封装对应的DSL语句
- 查询关键字 模糊匹配
- 过滤(分类,品牌,属性,价格区间,库存…)
- 排序
- 分页
- 高亮
GET /product/_search
{"query": {"bool": {"must": [{"match": {"subTitle": "华为"}}],"filter": [{"term": {"catalogId": "225"}},{"terms": {"brandId": ["13","16","14"]}},{"range": {"skuPrice": {"gte": 10,"lte": 12000}}},{"nested": {"path": "attrs","query": {"bool": {"must": [{"term": {"attrs.attrId": {"value": "9"}}},{"terms": {"attrs.attrValue": ["12","08","11"]}}]}}}}]}},"sort": [{"skuPrice": {"order": "desc"}}],"from": 0,"size": 20,"highlight": {"fields": {"subTitle": {}},"pre_tags": "<b style='color:red'>","post_tags": "<b>"}
}
2.3 构建SearchRequest对象
根据客户端提交的检索的信息,我们需要封装为对应的SearchRequest对象,然后通过ES的API来检索数据。
/*** 构建检索的请求* 模糊匹配,关键字匹配* 过滤(类别,品牌,属性,价格区间,库存)* 排序* 分页* 高亮* 聚合分析* @param param* @return*/private SearchRequest buildSearchRequest(SearchParam param) {SearchRequest searchRequest = new SearchRequest();searchRequest.indices(ESConstant.PRODUCT_INDEX);SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();// 构建具体的检索的条件// 1.构建bool查询BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();// 1.1 关键字的条件if(!StringUtils.isEmpty(param.getKeyword())){boolQuery.must(QueryBuilders.matchQuery("subTitle",param.getKeyword()));}// 1.2 类别的检索条件if(param.getCatalog3Id() != null){boolQuery.filter(QueryBuilders.termQuery("catalogId",param.getCatalog3Id()));}// 1.3 品牌的检索条件if(param.getBrandId() != null && param.getBrandId().size() > 0){boolQuery.filter(QueryBuilders.termsQuery("brandId",param.getBrandId()));}// 1.4 是否有库存if(param.getHasStock() != null){boolQuery.filter(QueryBuilders.termQuery("hasStock",param.getHasStock() == 1));}// 1.5 根据价格区间来检索if(!StringUtils.isEmpty(param.getSkuPrice())){String[] msg = param.getSkuPrice().split("_");RangeQueryBuilder skuPrice = QueryBuilders.rangeQuery("skuPrice");if(msg.length == 2){// 说明是 200_300skuPrice.gte(msg[0]);skuPrice.lte(msg[1]);}else if(msg.length == 1){// 说明是 _300 200_if(param.getSkuPrice().endsWith("_")){// 说明是 200_skuPrice.gte(msg[0]);}if(param.getSkuPrice().startsWith("_")){// 说明是 _300skuPrice.lte(msg[0]);}}boolQuery.filter(skuPrice);}// 1.6 属性的检索条件 attrs=20_8英寸:10英寸&attrs=19_64GB:32GBif(param.getAttrs() != null && param.getAttrs().size() > 0){for (String attrStr : param.getAttrs()) {BoolQueryBuilder boolNestedQuery = QueryBuilders.boolQuery();// attrs=19_64GB:32GB 我们首先需要根据 _ 做分割String[] attrStrArray = attrStr.split("_");// 属性的编号String attrId = attrStrArray[0];// 64GB:32GB 获取属性的值String[] values = attrStrArray[1].split(":");// 拼接组合条件boolNestedQuery.must(QueryBuilders.termQuery("attrs.attrId",attrId));boolNestedQuery.must(QueryBuilders.termsQuery("attrs.attrValue",values));NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery("attrs", boolNestedQuery, ScoreMode.None);boolQuery.filter(nestedQuery);}}sourceBuilder.query(boolQuery);// 2.排序if(!StringUtils.isEmpty(param.getSort())){// sort=salaCount_asc/descString[] s = param.getSort().split("_");SortOrder order = s[1].equalsIgnoreCase("asc")?SortOrder.ASC:SortOrder.DESC;sourceBuilder.sort(s[0], order);}// 3.处理分页// Integer pageNum; // 页码if(param.getPageNum() != null){// 需要做分页处理 pageSize = 5// pageNum:1 from:0 [0,1,2,3,4]// pageNum:2 from:5 [5,6,7,8,9]// from = ( pageNum - 1 ) * pageSizesourceBuilder.from( (param.getPageNum() - 1 ) * ESConstant.PRODUCT_PAGESIZE);sourceBuilder.size(ESConstant.PRODUCT_PAGESIZE);}// 4. 设置高亮if(!StringUtils.isEmpty(param.getKeyword())){// 如果有根据关键字查询那么我们才需要高亮设置HighlightBuilder highlightBuilder = new HighlightBuilder();highlightBuilder.field("subTitle");highlightBuilder.preTags("<b style='color:red'>");highlightBuilder.postTags("</b>");sourceBuilder.highlighter(highlightBuilder);}// 5.聚合运算// 5.1 品牌的聚合TermsAggregationBuilder brand_agg = AggregationBuilders.terms("brand_agg");brand_agg.field("brandId");brand_agg.size(50);// 品牌的子聚合brand_agg.subAggregation(AggregationBuilders.terms("brand_name_agg").field("brandName").size(10));brand_agg.subAggregation(AggregationBuilders.terms("brand_img_agg").field("brandImg").size(10));sourceBuilder.aggregation(brand_agg);// 5.2 类别的聚合TermsAggregationBuilder catalog_agg = AggregationBuilders.terms("catalog_agg");catalog_agg.field("catalogId");catalog_agg.size(10);// 类别的子聚合catalog_agg.subAggregation(AggregationBuilders.terms("catalog_name_agg").field("catalogName").size(10));sourceBuilder.aggregation(catalog_agg);// 5.3 属性的聚合NestedAggregationBuilder attr_agg = AggregationBuilders.nested("attr_agg", "attrs");// 属性id聚合TermsAggregationBuilder attr_id_agg = AggregationBuilders.terms("attr_id_agg");attr_id_agg.field("attrs.attrId");attr_id_agg.size(10);// 属性id下的子聚合 属性名称和属性值attr_id_agg.subAggregation(AggregationBuilders.terms("attr_name_agg").field("attrs.attrName").size(10));attr_id_agg.subAggregation(AggregationBuilders.terms("attr_value_agg").field("attrs.attrValue").size(10));attr_agg.subAggregation(attr_id_agg);sourceBuilder.aggregation(attr_agg);System.out.println(sourceBuilder.toString());searchRequest.source(sourceBuilder);return searchRequest;}
2.4 构建SearchResult对象
当我们通过封装的SearchRequest对象从ES中检索出了相关的信息后,我们需要将返回的SearchResponse对象封装为前端接收的SearchResult对象。
- 所有的满足条件的商品
- 分页相关的信息
- 当前商品涉及的品牌信息
- 当前商品涉及的类别信息
- 当前商品涉及的属性信息
/*** 根据检索的结果解析封装为SearchResult对象* @param response* @return*/private SearchResult buildSearchResult(SearchResponse response,SearchParam param){SearchResult result = new SearchResult();SearchHits hits = response.getHits();// 1.检索的所有商品信息SearchHit[] products = hits.getHits();List<SkuESModel> esModels = new ArrayList<>();if(products != null && products.length > 0){for (SearchHit product : products) {String sourceAsString = product.getSourceAsString();// 把json格式的字符串通过fastjson转换为SkuESModel对象SkuESModel model = JSON.parseObject(sourceAsString, SkuESModel.class);if(!StringUtils.isEmpty(param.getKeyword())){// 我们需要设置高亮HighlightField subTitle = product.getHighlightFields().get("subTitle");String subTitleHighlight = subTitle.getFragments()[0].string();model.setSubTitle(subTitleHighlight); // 设置高亮}esModels.add(model);}}result.setProducts(esModels);Aggregations aggregations = response.getAggregations();// 2.当前商品所涉及到的所有的品牌ParsedLongTerms brand_agg = aggregations.get("brand_agg");List<? extends Terms.Bucket> buckets = brand_agg.getBuckets();// 存储所有品牌的容器List<SearchResult.BrandVO> brandVOS = new ArrayList<>();if(buckets!=null && buckets.size() > 0){for (Terms.Bucket bucket : buckets) {SearchResult.BrandVO brandVO = new SearchResult.BrandVO();// 获取品牌的keyString keyAsString = bucket.getKeyAsString();brandVO.setBrandId(Long.parseLong(keyAsString)); // 设置品牌的编号// 然后我们需要获取品牌的名称和图片的地址ParsedStringTerms brand_img_agg = bucket.getAggregations().get("brand_img_agg");List<? extends Terms.Bucket> bucketsImg = brand_img_agg.getBuckets();if(bucketsImg != null && bucketsImg.size() > 0){String img = bucketsImg.get(0).getKeyAsString();brandVO.setBrandImg(img);}// 获取品牌名称的信息ParsedStringTerms brand_name_agg = bucket.getAggregations().get("brand_name_agg");String breadName = brand_name_agg.getBuckets().get(0).getKeyAsString();brandVO.setBrandName(breadName);brandVOS.add(brandVO);}}result.setBrands(brandVOS);// 3.当前商品涉及到的所有的类别信息ParsedLongTerms catalog_agg = aggregations.get("catalog_agg");List<? extends Terms.Bucket> bucketsCatalogs = catalog_agg.getBuckets();// 创建一个保存所有类别的容器List<SearchResult.CatalogVO> catalogVOS = new ArrayList<>();if(bucketsCatalogs != null && bucketsCatalogs.size() > 0){for (Terms.Bucket bucket : bucketsCatalogs) {SearchResult.CatalogVO catalogVO = new SearchResult.CatalogVO();String keyAsString = bucket.getKeyAsString(); // 获取类别的编号catalogVO.setCatalogId(Long.parseLong(keyAsString));// 获取类别的名称ParsedStringTerms catalog_name_agg = bucket.getAggregations().get("catalog_name_agg");String catalogName = catalog_name_agg.getBuckets().get(0).getKeyAsString();catalogVO.setCatalogName(catalogName);catalogVOS.add(catalogVO);}}result.setCatalogs(catalogVOS);// 4.当前商品涉及到的所有的属性信息ParsedNested attr_agg = aggregations.get("attr_agg");ParsedLongTerms attr_id_agg = attr_agg.getAggregations().get("attr_id_agg");List<? extends Terms.Bucket> bucketsAttr = attr_id_agg.getBuckets();List<SearchResult.AttrVo > attrVos = new ArrayList<>();if(bucketsAttr != null && bucketsAttr.size() > 0){for (Terms.Bucket bucket : bucketsAttr) {SearchResult.AttrVo attrVo = new SearchResult.AttrVo();// 获取属性的编号String keyAsString = bucket.getKeyAsString();attrVo.setAttrId(Long.parseLong(keyAsString));// 又得分别获取 属性的名称 和 属性的值ParsedStringTerms attr_name_agg = bucket.getAggregations().get("attr_name_agg");String attrName = attr_name_agg.getBuckets().get(0).getKeyAsString(); // 属性的名称attrVo.setAttrName(attrName);ParsedStringTerms attr_value_agg = bucket.getAggregations().get("attr_value_agg");if(attr_value_agg.getBuckets() != null && attr_value_agg.getBuckets().size() > 0 ){List<String> values = attr_value_agg.getBuckets().stream().map(item -> {String keyAsString1 = item.getKeyAsString();return keyAsString1;}).collect(Collectors.toList());attrVo.setAttrValue(values);}attrVos.add(attrVo);}}result.setAttrs(attrVos);// 5. 分页信息 当前页 总的记录数 总页数long total = hits.getTotalHits().value;result.setTotal(total);// 设置总记录数 6 /5 1+1result.setPageNum(param.getPageNum()); // 设置当前页long totalPage = total % ESConstant.PRODUCT_PAGESIZE == 0 ? total / ESConstant.PRODUCT_PAGESIZE : (total / ESConstant.PRODUCT_PAGESIZE + 1);result.setTotalPages((int)totalPage); // 设置总的页数return result;}
相关文章:

【业务功能篇90】微服务-springcloud-检索服务-ElasticSearch实战运用-DSL语句
商城检索服务 1.检索页面的搭建 商品检索页面我们放在search服务中处理,首页我们需要在mall-search服务中支持Thymeleaf。添加对应的依赖 <!-- 添加Thymeleaf的依赖 --><dependency><groupId>org.springframework.boot</groupId><artifa…...

QTday4
实现闹钟功能 1》 头文件 #ifndef BURGER_H #define BURGER_H#include <QWidget> #include <QLabel> #include <QLineEdit> #include <QPushButton> #include <QTextEdit> #include <QTimerEvent> //定时器事件类 #include <QDateTim…...

设计模式之命令模式(Command)的C++实现
1、命令模式的提出 在软件开发过程中,“行为请求者”和“行为实现者”通常呈现一种“紧耦合”,如果行为的实现经常变化,则不利于代码的维护。命令模式可以将行为的请求者和行为的实现者进行解耦。具体流程是将行为请求者封装成一个对象&…...

取证工具prodiscover的基本操作
前言提醒 取证工具ProDiscover在网上讲解操作的文章实在太少,一是prodiscover是用于磁盘取证的工具,本身比较小众比不上其他的编程软件能用到的地方多,二是这个工具是用来恢复提取磁盘中被删除的文件,是比较隐晦的软件。 需要注…...

flutter plugins插件【二】【FlutterAssetsGenerator】
2、FlutterAssetsGenerator 介绍地址:https://juejin.cn/post/6898542896274735117 配置assets目录 插件会从pubspec.yaml文件下读取assets目录,因此要使用本插件,你需要在pubspec.yaml下配置资源目录 flutter:# The following line ens…...

看懂UML类图
UML 统一建模语言(Unified Modeling Language,UML)是一种为面向对象系统的产品进行说明、可视化和编制文档的一种标准语言,是非专利的第三代建模和规约语言。UML是面向对象设计的建模工具,独立于任何具体程序设计语言。 类的表示 首先看那个…...

keras深度学习框架通过简单神经网络实现手写数字识别
背景 keras深度学习框架,并不是一个独立的深度学习框架,它后台依赖tensorflow或者theano。大部分开发者应该使用的是tensorflow。keras可以很方便的像搭积木一样根据模型搭出我们需要的神经网络,然后进行编译,训练,测试…...

React 中的 ref 如何操作 dom节点,使输入框获取焦点
聚焦文字输入框 .focus() 获取焦点 当用户点击按钮时,handleClick 函数会被调用,从而将焦点聚焦到文本输入框上。 // 焦文字输入框 import { useRef } from "react";const FocusForm () > {const inputRef useRef<any>(null);func…...

最短路Dijkstra,spfa,图论二分图算法AYIT---ACM训练(模板版)
文章目录 前言A - Dijkstra Algorithm0x00 算法题目0x01 算法思路0x02 代码实现 B - 最长路0x00 算法题目0x01 算法思路0x02 代码实现 C - 二分图最大匹配0x00 算法题目0x01 算法思路0x02 代码实现 D - 搭配飞行员0x00 算法题目0x01 算法思路0x02 代码实现 E - The Perfect Sta…...

AK 微众银行 9.3 笔试 Java后端方向
T1(模拟,二分) (没看清买的糖果只有前缀,一开始用二分写了,后来意识到也没改了,简单写的话,直接模拟就好了) #include <bits/stdc.h>#define endl \nusing namespace std;const int N 50010;int n; int a[N];bool check(…...

了解java中的通配符“?“
目录 通配符的作用 先看一段代码 用通配符"?"后,代码变化 结论 通配符上界 通配符下界 对通配符上下界的注释理解及其练习代码 简记: ? 用于在泛型的使用,即为通配符. 在Java中,通配符(wildcard)主要用于泛型…...

浙大陈越何钦铭数据结构07-图6 旅游规划【最小堆实现】
题目: 题目和浙大陈越何钦铭数据结构07-图6 旅游规划是一样的,不同的是用最小堆实现函数【FindMinDist】。 时间复杂度对比: 浙大陈越何钦铭数据结构07-图6 旅游规划: 创建图(CreateGraph):时…...

OpenShift 4 - 用 Prometheus 和 Grafana 监视用户应用定制的观测指标(视频)
《OpenShift / RHEL / DevSecOps 汇总目录》 说明:本文已经在 OpenShift 4.13 的环境中验证 文章目录 OpenShift 的监控功能构成部署被监控应用用 OpenShift 内置功能监控应用用 Grafana 监控应用安装 Grafana 运行环境配置 Grafana 数据源定制监控 Dashboard 演示视…...

【LeetCode】剑指 Offer <二刷>(3)
目录 题目:剑指 Offer 06. 从尾到头打印链表 - 力扣(LeetCode) 题目的接口: 解题思路: 代码: 过啦!!! 题目:剑指 Offer 07. 重建二叉树 - 力扣…...

Ceph IO流程及数据分布
1. Ceph IO流程及数据分布 1.1 正常IO流程图 步骤: client 创建cluster handler。client 读取配置文件。client 连接上monitor,获取集群map信息。client 读写io 根据crshmap 算法请求对应的主osd数据节点。主osd数据节点同时写入另外两个副本节点数据。…...

Netty-NIO
文章目录 一、NIO-Selector1.处理accept2.cancel3.处理read4.处理客户端断开5. 处理消息的边界6. 写入内容过多的问题7. 处理可写事件 一、NIO-Selector 1.处理accept //1.创建selector,管理多个channel Selector selector Selector.open(); ByteBuffer buffer ByteBuffer.…...

红外物理学习笔记 ——第三章
第三章 基尔霍夫定律:就是说物体热平衡条件下,发射的辐射功率要等于吸收的辐射功率 M α E M\alpha E MαE α \alpha α 是吸收率, M M M 是幅出度(发射出去的), E E E是辐照度(外面照过来的…...

使用 htmx 构建交互式 Web 应用
学习目标:了解htmx的基本概念、特点和用法,并能够运用htmx来创建交互式的Web应用程序。 学习内容: 1. 什么是htmx? - htmx是一种用于构建交互式Web应用程序的JavaScript库。 - 它通过将HTML扩展为一种声明性的交互式语言&a…...

S32K324芯片学习笔记
文章目录 Core and architectureDMASystem and power managementMemory and memory interfacesClocksSecurity and integrity安全与完整性Safety ISO26262Analog、Timers功能框图内存mapflash Signal MultiplexingPort和MSCR寄存器的mapping Core and architecture 两个Arm Co…...

htmx-使HTML更强大
本文作者是360奇舞团开发工程师 htmx 让我们先来看一段俳句: javascript fatigue: longing for a hypertext already in hand 这个俳句很有意思,是开源项目htmx文档中写的,意思是说,我们已经有了超文本,为什么还要去使用javascr…...

Java学习之序列化
1、引言 《手册》第 9 页 “OOP 规约” 部分有一段关于序列化的约定 1: 【强制】当序列化类新增属性时,请不要修改 serialVersionUID 字段,以避免反序列失败;如果完全不兼容升级,避免反序列化混乱,那么请…...

C++实现蜂群涌现效果(flocking)
Flocking算法0704_元宇宙中的程序员的博客-CSDN博客 每个个体的位置,通过计算与周围个体的速度、角度、位置,去更新位置。...

IDEA复制一个工程为多个并启动,测试负载均衡
1 找到服务按钮 2 选择复制配置 3 更改新的名称与虚拟机参数 复制下面的代码在VM参数中 -Dserver.port8082 4 最后启动即可...

001_C++语法基础
C语法基础 所有C语法要用英文区分大小写每个语句写完以分号结束 C标准输入输出头文件iostream 若想通过C实现数据的输入和输出,需要导入标准输入输出头文件 #include <iostream>标准输入输出头文件<iostream>中包含了cin输入语句和cout输出语句 标…...

对Excel表中归类的文件夹进行自动分类
首先把excel表另存为.txt文件(注意:刚开始可能是ANSI格式,需要转成UTF-8格式);再新建一个.txt文件,重命名成.bat文件(注意:直接创建的如果是是UTF-8格式,最好转成ANSI格式࿰…...

LabVIEW液压支架控制系统的使用与各种配置的预测模型的比较分析
LabVIEW液压支架控制系统的使用与各种配置的预测模型的比较分析 模型预测控制在工业中应用广泛。这种方法的优点之一是在求解最优控制问题时能够明确考虑对输入和输出状态施加的约束。控制对象模型用于有限时间范围内最优控制的实时计算。所使用的数学设备允许从具有单输入和单…...

C++中位运算符使用
& 与 只有都为1结果为1 0 & 0 00 & 1 01 & 0 01 & 1 1 | 或 只要一个为1结果为1 0|00 0|11 1|01 1|11 ^ 异或 两个相同的数字为0,其余为1 0^00 1^01 0^11 1^10 ~ 取反 将进制位数进行取反 ~1-2 //0000 0001-->代…...

微机原理 || 第2次测试:汇编指令(加减乘除运算,XOR,PUSH,POP,寻址方式,物理地址公式,状态标志位)(测试题+手写解析)
(一)测试题目: 1.数[X]补1111,1110B,则其真值为 2.在I/O指令中,可用于表示端口地址的寄存器 3. MOV AX,[BXSl]的指令中,源操作数的物理地址应该如何计算 4.执行以下两条指令后,标志寄存器FLAGS的六个状态…...

人员闯入检测告警算法
人员闯入检测告警算法通过yolov5网络模型识别检测算法,人员闯入检测告警算法对未经许可或非法进入的人员进行及时识别告警,确保对危险区域的安全管理和保护。YOLO系列算法是一类典型的one-stage目标检测算法,其利用anchor box将分类与目标定位…...

python中super()用法
super关键字的用法 一、概述二、作用三、语法四、使用示例1.通过super() 来调用父类的__init__ 构造方法:2.通过supper() 来调用与子类同名的父类方法2.1 单继承2.2 多继承 一、概述 super() 是python 中调用父类(超类)的一种方法࿰…...