当前位置: 首页 > news >正文

Elasticsearch(十五)搜索---搜索匹配功能⑥--基于地理位置查询

一、前言

随着互联网+的热门,越来越多的传统行业将全部或者部分业务转移到互联网上,其中不乏一些和地理位置强相关的行业。基于地理位置的搜索功能,大大提升了人们的生活和工作效率。例如,外出旅行时,只需要用手机打开订酒店的应用软件,查找附近心仪的酒店下单即可;又或者打车行业,人们不用在寒冷的户外拦截出租车,只需要在室内打开打车APP定位到当前位置,然后确定目的地,系统就可以为附近的车辆派发订单。
幸运的是,ES为用户提供了基于地理位置的搜索功能。它主要支持两种类型的地理查询:一种是地理点(geo_point),即经纬度查询,另一种是地理形状查询(geo_shape),即支持点、线、圆形和多边形查询等。
从实用性来说,地理点(即geo_point)数据类型的使用的更多一些,本节也只对地理点类型进行介绍。
对应于geo_point字段类型的查询方式有3种,分别为geo_distance查询、geo_bounding_box查询和geo_polygon
为了更方便专一的学习地理搜索,我们在hotel索引批量增加多条文档,内容如下:

POST /hotel_location/_doc/_bulk
{"index":{"_id":51}}
{"title":"连锁酒店1","location":{"lat":"40.17836693398477","lon":"116.64002551005981"}}
{"index":{"_id":52}}
{"title":"连锁酒店2","location":{"lat":"40.19103839805197","lon":"116.5624013764374"}}
{"index":{"_id":53}}
{"title":"连锁酒店3","location":{"lat":"40.13933715136454","lon":"116.63441990026217"}}
{"index":{"_id":54}}
{"title":"连锁酒店4","location":{"lat":"40.14901664712196","lon":"116.53067995860928"}}
{"index":{"_id":55}}
{"title":"连锁酒店5","location":{"lat":"40.125057718315716","lon":"116.62963567059545"}}
{"index":{"_id":56}}
{"title":"连锁酒店6","location":{"lat":"40.19216257806647","lon":"116.64025980109571"}}
{"index":{"_id":57}}
{"title":"连锁酒店7","location":{"lat":"40.16371689899584","lon":"116.63095084701624"}}
{"index":{"_id":58}}
{"title":"连锁酒店8","location":{"lat":"40.146045218040605","lon":"116.5696251832195"}}
{"index":{"_id":59}}
{"title":"连锁酒店9","location":{"lat":"40.144735806234166","lon":"116.60712460957835"}}

通过上面的步骤,我们完成了9条经纬度数据的插入;可以通过search语句查询一下结果

二、geo_bounding_box

geo_bounding_box语法又称为地理坐标盒模型,在当前语法中,只需选择一个矩阵范围(输入矩阵的左上角的顶点地理坐标和矩阵的右上角的顶点地理坐标,构建成为一个矩阵),即可计算出当前矩阵中符合条件的元素;
![在这里插入图片描述](https://img-blog.csdnimg.cn/d1e52cc370f94779b7261c47c0974bba.png

简单来说呢,就是给定两个坐标,通过这两个坐标形成对角线,平行于地球经纬度从而得到的一个矩阵。采用geo_bounding_box语法可以得到坐落于当前矩阵中的元素的信息;
假设如上图我这边给定两个坐标,分别是A(116.498353,40.187328) 和 B(116.610461,40.084509),这样我们就得到了一个矩阵。
ES的geo_bounding_box语法有很多种查询方式,但是需要注意的是我们要确定好哪个是左上角的坐标,哪个是右下角的坐标,并且这两个坐标不能互换
那上面的例子通过A\B两点去找矩阵范围内的酒店,DSL如下

GET /hotel/_search
{"query": {"geo_bounding_box": {"location": {"top_left": {"lat": 40.187328,"lon": 116.498353},"bottom_right": {"lat": 40.084509,"lon": 116.610461}}}}
}

输出如下,可以看到有3家酒店位于这个矩阵范围中:

{..."hits" : {"total" : {"value" : 3,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "hotel","_type" : "_doc","_id" : "54","_score" : 1.0,"_source" : {"title" : "连锁酒店4","location" : {"lon" : "116.53067995860928","lat" : "40.14901664712196"}}},{"_index" : "hotel","_type" : "_doc","_id" : "58","_score" : 1.0,"_source" : {"title" : "连锁酒店8","location" : {"lon" : "116.5696251832195","lat" : "40.146045218040605"}}},{"_index" : "hotel","_type" : "_doc","_id" : "59","_score" : 1.0,"_source" : {"title" : "连锁酒店9","location" : {"lon" : "116.60712460957835","lat" : "40.144735806234166"}}}]}
}

那么除了上面的查询的DSL语法之外,还有如下语法,获取的结果和上面DSL均相同:

  1. 基于经纬度数组的DSL语法

需要注意的是,数组形式的,经纬度顺序需调换一下
这样就不需要输入lat和lon了,直接通过数组表示经纬度

GET /hotel/_search
{"query": {"geo_bounding_box": {"location": {"top_left": [116.498353,40.187328],"bottom_right": [116.610461,40.084509]}}}
}
  1. 基于经纬度字符串的DSL语法

字符串不同于数组,经纬度顺序不需要调换

GET /hotel/_search
{"query": {"geo_bounding_box": {"location": {"top_left": "40.187328,116.498353","bottom_right": "40.084509,116.610461"}}}
}
  1. 基于经纬度边界框WKT的DSL语法

可以看到先是A的经度,再是B的经度,然后是A的纬度,再是B的纬度,通过BBOX封装

GET /hotel/_search
{"query": {"geo_bounding_box": {"location": {"wkt": "BBOX (116.498353,116.610461,40.187328,40.084509)"}}}
}
  1. 基于经纬度GeoHash的DSL语法
//关于GeoHash可以参考两个网址
// 全球GeoHash地图 http://geohash.gofreerange.com/
// GeoHash坐标在线转换 http://geohash.co/
GET /hotel/_search
{"query": {"geo_bounding_box": {"location": {"top_left": "wx4udgz","bottom_right": "wx4uj91"}}}
}
  1. 基于经纬度顶点属性的DSL语法
    相当于把top_left和bottom_right分成了四个
GET /hotel/_search
{"query": {"geo_bounding_box": {"location": {"top": 40.187328,"left": 116.498353,"bottom": 40.084509,"right": 116.610461}}}
}

至此,采用上述6种方式计算的矩阵坐落元素所执行结果均一致,且逐个在地图上核实,所召回的建筑均真实的在上图的矩阵中;
计算某个矩阵或者是多边形中的元素,在Redis中目前是不支持的,在这方面ES表现的更为强大;通过上述的三种语法可以看到,ES可以很好的支持 矩阵、圆、多边形的空间地理检索,通过查看Redis的语法可以看到Redis目前只支持圆的空间地理检索

在java客户端使用new GeoBoundingBoxQueryBuilder()构造geo_bounding_box请求,我们可以看到它有很多附加的方法
在这里插入图片描述
但是我们这次使用的主要是setCorners()设置两点距离,可以看到它支持geoHash,两点坐标,经纬度顶点等查询方法。
在这里插入图片描述
我们使用两点坐标来进行查询
Service如下:

public List<Hotel> geoBoundingBoxQuery(HotelDocRequest hotelDocRequest) throws IOException {//新建搜索请求String indexName = getNotNullIndexName(hotelDocRequest);SearchRequest searchRequest = new SearchRequest(indexName);SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();// 构造左上点坐标GeoPoint topLeft = new GeoPoint(40.187328D, 116.498353D);// 构造右下点坐标GeoPoint bottomRight = new GeoPoint(40.084509D, 116.610461D);GeoBoundingBoxQueryBuilder geoBoundingBoxQueryBuilder = new GeoBoundingBoxQueryBuilder("location").setCorners(topLeft,bottomRight);searchSourceBuilder.query(geoBoundingBoxQueryBuilder);searchRequest.source(searchSourceBuilder);return getQueryResult(searchRequest);}

这次getQueryResult(),我们需要将结果能够正常返回location这个属性
首先我们建立Location这个类,lat代表纬度,lon代表经度:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Location {private String lat;private String lon;
}

然后在hotel索引类增加location属性,这个属性名和你建造索引用的是一样的:
在这里插入图片描述
然后对getQueryResult进行改造,因为我们获取到location的json对象其实是类似于hashMap结构的对象,我们可以使用JSONUtil.toJsonStr(location)将其先转化为json字符串,然后通过JSONUtil.toBean(String jsonString,T)转化成我们的目标对象Location。
完整代码如下:

private List<Hotel> getQueryResult(SearchRequest searchRequest) throws IOException {ArrayList<Hotel> resultList = new ArrayList<>();SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);RestStatus status = searchResponse.status();if (status != RestStatus.OK) {return Collections.emptyList();}SearchHits searchHits = searchResponse.getHits();for (SearchHit searchHit : searchHits) {Hotel hotelResult = new Hotel();hotelResult.setId(searchHit.getId());   //文档_idhotelResult.setIndex(searchHit.getIndex());   //索引名称hotelResult.setScore(searchHit.getScore());   //文档得分//转换为MapMap<String, Object> dataMap = searchHit.getSourceAsMap();hotelResult.setTitle((String) dataMap.get("title"));hotelResult.setCity((String) dataMap.get("city"));Object price = dataMap.get("price");if (price != null) {hotelResult.setPrice(Double.valueOf((String) price));}//获取locationObject location = dataMap.get("location");if (location != null) {hotelResult.setLocation(JSONUtil.toBean(JSONUtil.toJsonStr(location), Location.class));}resultList.add(hotelResult);}return resultList;}

然后回到controller调用:

	@PostMapping("/query/bounding-box")public FoundationResponse<List<Hotel>> geoBoundingBoxQuery(@RequestBody HotelDocRequest hotelDocRequest) {try {List<Hotel> hotelList = esQueryService.geoBoundingBoxQuery(hotelDocRequest);if (CollUtil.isNotEmpty(hotelList)) {return FoundationResponse.success(hotelList);} else {return FoundationResponse.error(100,"no data");}} catch (IOException e) {log.warn("搜索发生异常,原因为:{}", e.getMessage());return FoundationResponse.error(100, e.getMessage());} catch (Exception e) {log.error("服务发生异常,原因为:{}", e.getMessage());return FoundationResponse.error(100, e.getMessage());}}

postman调用截图:
在这里插入图片描述

三、geo_distance

ES中的geo_distance语法与Redis中的georadius语法类似,通过给定一个坐标和半径,圈出圆内的点。在ES可以定义一些排序规则返回召回结果集数据与当前坐标的距离,Redis中默认返回了距离;
与geo_bounding_box语法类似,geo_distance语法也有多种查询方式,如 经纬度属性、经纬度数组、经纬度字符串、GeoHash等,下面就简单的以 经纬度字符串为例进行演示,重新选定坐标,以纬度(116.5864,40.174697)为例,查询3km范围内的酒店

GET /hotel/_search
{"query": {"geo_distance":{"distance":"3km","location":"40.174697,116.5864"}}
}

查询结果如下:

{..."hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "hotel","_type" : "_doc","_id" : "52","_score" : 1.0,"_source" : {"title" : "连锁酒店2","location" : "40.19103839805197,116.5624013764374"}}]}
}

而geo_distance和后面我们的sort排序用的很紧密,例如微信附近的人就可以通过该功能实现,其中结合sort可以返回当前位置与目标位置之间的距离。这个我们后面会介绍。
在Java客户端可以使用new GeoDistanceQueryBuilder()构造geo_distance查询,通过distance()设置以指定坐标点为中心的半径大小以及距离的单位,point()设置指定坐标点,service如下:

	public List<Hotel> geoDistanceQuery(HotelDocRequest hotelDocRequest) throws IOException {//新建搜索请求String indexName = getNotNullIndexName(hotelDocRequest);SearchRequest searchRequest = new SearchRequest(indexName);SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();// 假设目标距离坐标GeoPoint sourcePoint = new GeoPoint(40.174697D, 116.5864D);GeoDistanceQueryBuilder geoDistanceQueryBuilder = new GeoDistanceQueryBuilder("location").distance("3", DistanceUnit.KILOMETERS).point(sourcePoint);searchSourceBuilder.query(geoDistanceQueryBuilder);searchRequest.source(searchSourceBuilder);return getQueryResult(searchRequest);}

controller如下:

	@PostMapping("/query/geo-distance")public FoundationResponse<List<Hotel>> geoDistanceQuery(@RequestBody HotelDocRequest hotelDocRequest) {try {List<Hotel> hotelList = esQueryService.geoDistanceQuery(hotelDocRequest);if (CollUtil.isNotEmpty(hotelList)) {return FoundationResponse.success(hotelList);} else {return FoundationResponse.error(100, "no data");}} catch (IOException e) {log.warn("搜索发生异常,原因为:{}", e.getMessage());return FoundationResponse.error(100, e.getMessage());} catch (Exception e) {log.error("服务发生异常,原因为:{}", e.getMessage());return FoundationResponse.error(100, e.getMessage());}}

postman截图如下:
在这里插入图片描述

四、geo_polygon

ES的geo_polygon语法,可以通过指定多个坐标点,从而构成一个多边形,然后从当前多边形中召回坐落其中的元素进行召回;在当前语法中,最少需要3个坐标,从而构成一个多边形;
例如我在ES增加一个我公司的坐标(121.530533,31.085692)
在这里插入图片描述

POST /hotel/_doc/031
{"title":"上海闵行浦江智谷","location":{"lat":"31.085692","lon":"121.530533"}
}

然后可以指定3个坐标,将公司位置坐落于这三个坐标中,看看公司位置是否可以检索出来,3个坐标在地图上的展示如下

坐标点A:(121.531257,31.085262)
坐标点B:(121.529694,31.085494)
坐标点C:(121.530632,31.086252)
在这里插入图片描述

ES的geo_polygon语法也支持多种语法,如 经纬度数组、经纬度字符串、GeoHash值等;这里就采用字符串演示了,另外两种语法不再赘述;其执行DSL如下

GET /hotel/_search
{"query": {"geo_polygon": {"location": {"points": ["31.085262,121.531257","31.085494, 121.529694","31.086252, 121.530632"]}}}
}

结果如下:

{..."hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "hotel","_type" : "_doc","_id" : "031","_score" : 1.0,"_source" : {"title" : "上海闵行浦江智谷","location" : {"lat" : "31.085692","lon" : "121.530533"}}}]}
}

可以看到,通过三个点构建成一个三角形,当目标元素坐落于所构建的形状中,即可很好的将其召回;

到这里,关于ES的geo_point语法已经接近尾声了,简单的了解了一下ES的空间地理支持;下面再新增一种相对复杂一点的地形,看看geo_polygon语法可以很好的支持不。

通过刚才的3个坐标,我们新增一个坐标,构建一个凹形的多边形,将目标节点剔除在多边形外,看看ES在这方面的支持如何,最终构建的多边形如下:
在这里插入图片描述

GET /hotel/_search
{"query": {"geo_polygon": {"location": {"points": ["31.085262,121.531257","31.086252, 121.530632","31.085494, 121.529694","31.085854,121.530524"]}}}
}

结果没有找到:
在这里插入图片描述
需要注意的是,查询语句输入的点的顺序是需要注意的,它会按照你输入的点的顺序构成不同的多边形,从而出现不同的结果,就像我上图那样的使用箭头标注顺序,如果我改变某个点的顺序,有可能就会把目标囊括进去从而和之前结果不一样。
那么在java客户端可以使用new GeoPolygonQueryBuilder ()构造geo_polygon查询,构造方法包含需要查询的字段以及可以接收一个GeoPoint数组,数组就和我们刚才DSL中输入的那些点是一样的,记住要按照顺序放,service如下:

public List<Hotel> geoPolygonQuery(HotelDocRequest hotelDocRequest) throws IOException {//新建搜索请求String indexName = getNotNullIndexName(hotelDocRequest);SearchRequest searchRequest = new SearchRequest(indexName);SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();// 假设目标距离坐标ArrayList<GeoPoint> geoPoints = new ArrayList<GeoPoint>();GeoPoint sourcePoint1 = new GeoPoint(31.085262D, 121.531257D);GeoPoint sourcePoint2 = new GeoPoint(31.085494D, 121.529694D);GeoPoint sourcePoint3 = new GeoPoint(31.086252D, 121.530632D);geoPoints.add(sourcePoint1);geoPoints.add(sourcePoint2);geoPoints.add(sourcePoint3);GeoPolygonQueryBuilder geoPolygonQueryBuilder = new GeoPolygonQueryBuilder("location", geoPoints);searchSourceBuilder.query(geoPolygonQueryBuilder);searchRequest.source(searchSourceBuilder);return getQueryResult(searchRequest);}

controller如下:

@PostMapping("/query/geo-polygon")public FoundationResponse<List<Hotel>> geoPolygonQuery(@RequestBody HotelDocRequest hotelDocRequest) {try {List<Hotel> hotelList = esQueryService.geoPolygonQuery(hotelDocRequest);if (CollUtil.isNotEmpty(hotelList)) {return FoundationResponse.success(hotelList);} else {return FoundationResponse.error(100, "no data");}} catch (IOException e) {log.warn("搜索发生异常,原因为:{}", e.getMessage());return FoundationResponse.error(100, e.getMessage());} catch (Exception e) {log.error("服务发生异常,原因为:{}", e.getMessage());return FoundationResponse.error(100, e.getMessage());}}

postman执行如下:
在这里插入图片描述

相关文章:

Elasticsearch(十五)搜索---搜索匹配功能⑥--基于地理位置查询

一、前言 随着互联网的热门&#xff0c;越来越多的传统行业将全部或者部分业务转移到互联网上&#xff0c;其中不乏一些和地理位置强相关的行业。基于地理位置的搜索功能&#xff0c;大大提升了人们的生活和工作效率。例如&#xff0c;外出旅行时&#xff0c;只需要用手机打开…...

为什么axios会有params和data两个参数

不知道大家有没有过这种感觉&#xff0c;突然一个问题百思不得其解&#xff0c;然后突然有一天就明白了。然后就感觉这个问题原来这么简单&#xff0c;本来想记录下来&#xff0c;但是又感觉这么简单的问题记录下来没啥意义。但是回过头来想一想&#xff0c;这个问题之前其实困…...

Vite+Vue3项目全局引入scss文件

前言 Sass 是世界上最成熟、最稳定、最强大的专业级CSS扩展语言&#xff01;在日常项目开发过程中使用非常广泛&#xff0c;今天主要讲一下 ViteVue3 项目中该如何全局引入 scss 文件&#xff0c;引入混合 mixin 文件的不同配置。捎带说一下 Vue2 中的引入方式做一下简单的对比…...

android10.0(Q) MTK 6765 user版本打开root权限

前言 相比较 Android8.1、9.0 而言&#xff0c;Android10.0 版本 的 root变得相当麻烦&#xff0c;10.0 中引入了动态分区机制&#xff0c;同样的要想完全 adb root&#xff0c;需要 fastboot 解锁&#xff0c;然后关闭 verity 才能 adb remount 成功。我尝试和之前一样修改 f…...

软考 系统架构设计师系列知识点之设计模式(9)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之设计模式&#xff08;8&#xff09; 所属章节&#xff1a; 老版&#xff08;第一版&#xff09;教材 第7章. 设计模式 第2节. 设计模式实例 相关试题 7. 一组对象以定义良好但是复杂的方式进行通信&#xff0c;产生…...

LeetCode二分查找

搜索插入位置 description 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示例 1: 输入: nums [1,3,5,6], tar…...

米软科技客户单病种上报量云南省第一

近日米软获悉&#xff0c;在云南省统计的单病种上报情况中&#xff0c;截止2021年11月15日&#xff0c;上线单病种系统不足半年的红河州第一人民医院&#xff08;云南省滇南中心医院&#xff09;以占全省上报总数5%的22950例&#xff0c;遥遥领先于同省各家二三级医院。 全省上…...

SpringCore完整学习教程5,入门级别

本章从第6章开始 6. JSON Spring Boot提供了三个JSON映射库的集成: Gson Jackson JSON-B Jackson是首选的和默认的库。 6.1. Jackson 为Jackson提供了自动配置&#xff0c;Jackson是spring-boot-starter-json的一部分。当Jackson在类路径上时&#xff0c;将自动配置Obj…...

1024 云上见 · 上云挑战(ChatGPT搭建)

【玩转1024】使用函数计算X通义千问搭建AI助手&#xff0c;参与1024小说创作大赛 【使用函数计算X通义千问搭建AI助手&#xff0c;参与小说创作大赛】&#xff1a;本活动基于函数计算X 通义千问快速部署 AI 个人助手应用&#xff0c;用户可以根据需要选择不同角色的AI助手开启…...

Linux内核代码中常用的数据结构

Linux内核代码中广泛使用了数据结构和算法&#xff0c;其中最常用的两个是链表和红黑树。 链表 Linux内核代码大量使用了链表这种数据结构。链表是在解决数组不能动态扩展这个缺陷而产生的一种数据结构。链表所包含的元素可以动态创建并插入和删除。 链表的每个元素都是离散…...

自动驾驶,从“宠儿”走进“淘汰赛”

从“一步到位”到场景、技术降维。从拼落地路径&#xff0c;到拼雷达、算力&#xff0c;再到如今的性价比之争&#xff0c;自动驾驶似乎变得愈发“接地气”。 作者|斗斗 编辑|皮爷 出品|产业家 比起去年&#xff0c;黄文欢和张放今年显得更加忙碌。 “自动驾驶赛道&…...

Tensorflow2 中模型训练标签顺序和预测结果标签顺序不一致问题解决办法

本篇文章将详细介绍Tensorflow2.x中模型训练标签顺序和预测结果标签顺序不一致问题&#xff0c;这个问题如果考虑不周&#xff0c;或者标签顺序没有控制好的情况下会出现预测结果精度极其不准确的情况。 训练数据集的结构&#xff1a;数据集有超过10的类别数&#xff0c;这里包…...

uniapp 在 Android Studio 模拟器中运行项目

在开发App时&#xff0c;无论是使用 Flutter 还是 React native&#xff0c;还是使用uni-app 开发跨端App时&#xff0c;总是需要运行调试。一般调试分为两种。 第一&#xff1a;真机调试 第二&#xff1a;模拟器调试 真机调试的好处是可以看到更好的效果&#xff0c;缺点就是…...

淘宝API接口获取商品信息,订单管理,库存管理,数据分析

在淘宝开放平台中&#xff0c;每个API接口都有相应的文档说明和授权机制&#xff0c;以确保数据的安全性和可靠性。开发者可以根据自己的需求选择相应的API接口&#xff0c;并根据文档说明进行调用和使用。 淘宝开放平台API接口是一套REST方式的开放应用程序编程接口&…...

Azure - 机器学习企业级服务概述与介绍

目录 一、什么是 Azure 机器学习&#xff1f;大规模生成业务关键型机器学习模型 二、Azure 机器学习适合哪些人群&#xff1f;三、Azure 机器学习的价值点加快价值实现速度协作并简化 MLOps信心十足地开发负责任地设计 四、端到端机器学习生命周期的支持准备数据生成和训练模型…...

Linux docker 安装 部署

docker 安装 linux系统离线安装docker 如何使用docker部署c/c程序 常用命令 给予 docker 访问 gui 的权限 在 /etc/profile 末尾添加 if [ "$DISPLAY" ! "" ] thenxhost fi在执行 更新 source /etc/profiledocker下载镜像 docker search gcc #搜索d…...

selenium+python web自动化测试框架项目实战实例教程

自动化测试对程序的回归测试更方便。 由于回归测试的动作和用例是完全设计好的,测试期望的结果也是完全可以预料的,将回归测试自动运行... 可以运行更加繁琐的测试 自动化测试的一个明显好处就是可以在很短的时间内运行更多的测试。学习自动化测试最终目的是应用到实际项目中&…...

软考高级系统架构设计师系列之:案例分析典型试题七

软考高级系统架构设计师系列之:案例分析典型试题七 一、架构评估1.案例试题2.参考答案一、架构评估 某网上购物电子商务公司拟升级正在使用的在线交易系统,以提高用户网上购物在线支付环节的效率和安全性。在系统的需求分析与架构设计阶段,公司提出的需求和关键质量属性场景…...

【算法|动态规划No30】leetcode5. 最长回文子串

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…...

计算机视觉 激光雷达结合无监督学习进行物体检测的工作原理

一、简述 激光雷达是目前正在改变世界的传感器。它集成在自动驾驶汽车、自主无人机、机器人、卫星、火箭等中。该传感器使用激光束了解世界,并测量激光击中目标返回所需的时间,输出是点云信息,利用这些信息,我们可以从3D点云中查找障碍物。 从自动驾驶汽车的角度看激光雷达…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...