Redis GEO實(shí)現(xiàn)附近搜索功能
公司最近來(lái)了一個(gè)新項(xiàng)目,做小程序招聘。其中有一個(gè)需求是實(shí)現(xiàn)附近崗位推薦。由于用戶量不大,決定采用redis來(lái)實(shí)現(xiàn)。之前沒(méi)有接觸過(guò)。現(xiàn)在用來(lái)記錄一下。(redis必須使用3.2及以上版本)
- 先說(shuō)一下大概流程。將職位ID和經(jīng)緯度存入redis中。每當(dāng)添加職位時(shí)就增加一條信息。當(dāng)用戶點(diǎn)擊附近時(shí),通過(guò)用戶的經(jīng)緯度來(lái)查詢它對(duì)應(yīng)的職位id,這樣就可以關(guān)聯(lián)起來(lái)查詢出職位信息返回用戶給予展示。
- 項(xiàng)目采用的spring cloud Alibaba全家桶,就不寫它的maven依賴,只編寫redis相關(guān)
引入redis依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.3.0.RELEASE</version> </dependency>
Bo
package cn.zxw.vo_bo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * @Author: zhangxiongwei * @Date: 2021-10-26 16:11 * @Description: 位置信息 */ @Data @ApiModel("位置信息") public class LocationBo { @ApiModelProperty("經(jīng)度") private Double longitude; @ApiModelProperty("緯度") private Double latitude; @ApiModelProperty("半徑") private Double radius; @ApiModelProperty("條數(shù)") private Long limit; }
redis配置類
package cn.zxw.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.BoundGeoOperations; import org.springframework.data.redis.core.RedisTemplate; /** * @Author: zhangxiongwei * @Date: 2021-10-26 16:38 * @Description: redi配置 */ @Configuration public class RedisConfig { /** * The constant GEO_STAGE. */ public static final String GEO_STAGE = "cities"; /** * Geo ops bound geo operations. * * @param redisTemplate the redis template * @return the bound geo operations */ @Bean public BoundGeoOperations<String, String> citiesGeoOps(RedisTemplate<String, String> redisTemplate) { // 清理緩存 redisTemplate.delete(GEO_STAGE); return redisTemplate.boundGeoOps(GEO_STAGE); } }
測(cè)試控制器
package cn.zxw.controller; import cn.zxw.result.CommonResult; import cn.zxw.vo_bo.LocationBo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.geo.*; import org.springframework.data.redis.connection.RedisGeoCommands; import org.springframework.data.redis.core.BoundGeoOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.*; import java.util.HashMap; import java.util.Map; /** * @Author: zhangxiongwei * @Date: 2021-10-26 15:41 * @Description: 附近推薦 */ @Slf4j @RestController @Api(tags = "redis", description = "redis控制") @RequestMapping("/geo") @AllArgsConstructor public class RedisGeoController { private static final String GEO_STAGE = "cities"; private final RedisTemplate<String, String> redisTemplate; private final BoundGeoOperations<String, String> citiesGeoOps; /** * 初始化數(shù)據(jù)可以將職位id和經(jīng)緯度存入redis, * 添加職業(yè)時(shí)增加位置數(shù)據(jù) * 當(dāng)用戶點(diǎn)擊附近是,傳入經(jīng)緯度。返回id獲得職位信息推送給用戶 */ @GetMapping("/init") @ApiOperation("初始化") public void init() { // 清理緩存 redisTemplate.delete(GEO_STAGE); Map<String, Point> points = new HashMap<>(); points.put("shijiazhuang", new Point(114.48, 38.03)); points.put("xingtang", new Point(114.54, 38.42)); points.put("guangcheng", new Point(114.84, 38.03)); points.put("gaoyi", new Point(114.58, 37.62)); points.put("zhaoxian", new Point(114.78, 37.76)); points.put("jinxing", new Point(114.13, 38.03)); points.put("luquan", new Point(114.03, 38.08)); points.put("xinle", new Point(114.67, 38.33)); points.put("zhengding", new Point(114.56, 38.13)); // 添加地理信息 redisTemplate.boundGeoOps(GEO_STAGE).add(points); } @PostMapping("/city") @ApiOperation("獲得城市") public CommonResult<GeoResults<RedisGeoCommands.GeoLocation<String>>> dis(@RequestBody LocationBo locationBo) { //設(shè)置當(dāng)前位置 Point point = new Point(locationBo.getLongitude(), locationBo.getLatitude()); //設(shè)置半徑范圍 Metric metric = RedisGeoCommands.DistanceUnit.METERS; Distance distance = new Distance(locationBo.getRadius(), metric); Circle circle = new Circle(point, distance); //設(shè)置參數(shù) 包括距離、坐標(biāo)、條數(shù) RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands .GeoRadiusCommandArgs .newGeoRadiusArgs() .includeDistance() .includeCoordinates() .sortAscending() .limit(locationBo.getLimit()); GeoResults<RedisGeoCommands.GeoLocation<String>> radius = citiesGeoOps.radius(circle, args); return CommonResult.success(radius); } }
測(cè)試數(shù)據(jù)
### 使用的是httpclient POST http://localhost:6001/geo/city Content-Type: application/json { "longitude": 114.56, "latitude": 38.13, "radius": 100000, "limit": 10 }
返回結(jié)果
{
"code": 200,
"message": "操作成功",
"data": {
"averageDistance": {
"value": 31642.19217777778,
"metric": "METERS",
"unit": "m",
"normalizedValue": 0.004961039905191403
},
"content": [
{
"content": {
"name": "zhengding",
"point": {
"x": 114.55999821424484,
"y": 38.12999923666221
}
},
"distance": {
"value": 0.1778,
"metric": "METERS",
"unit": "m",
"normalizedValue": 2.787647866453794E-8
}
},
{
"content": {
"name": "shijiazhuang",
"point": {
"x": 114.55999821424484,
"y": 38.02999941748397
}
},
"distance": {
"value": 13144.3531,
"metric": "METERS",
"unit": "m",
"normalizedValue": 0.0020608452123245394
}
},
{
"content": {
"name": "xinle",
"point": {
"x": 114.55999821424484,
"y": 38.329998875018696
}
},
"distance": {
"value": 24232.5609,
"metric": "METERS",
"unit": "m",
"normalizedValue": 0.0037993164618445796
}
},
{
"content": {
"name": "guangcheng",
"point": {
"x": 114.55999821424484,
"y": 38.02999941748397
}
},
"distance": {
"value": 26919.7324,
"metric": "METERS",
"unit": "m",
"normalizedValue": 0.004220626242427844
}
},
{
"content": {
"name": "xingtang",
"point": {
"x": 114.55999821424484,
"y": 38.419999219223335
}
},
"distance": {
"value": 32302.7819,
"metric": "METERS",
"unit": "m",
"normalizedValue": 0.005064610857371048
}
},
{
"content": {
"name": "jinxing",
"point": {
"x": 114.55999821424484,
"y": 38.02999941748397
}
},
"distance": {
"value": 39255.7243,
"metric": "METERS",
"unit": "m",
"normalizedValue": 0.006154732063610425
}
},
{
"content": {
"name": "zhaoxian",
"point": {
"x": 114.55999821424484,
"y": 37.760000919591185
}
},
"distance": {
"value": 45453.0791,
"metric": "METERS",
"unit": "m",
"normalizedValue": 0.007126388018946599
}
},
{
"content": {
"name": "luquan",
"point": {
"x": 114.55999821424484,
"y": 38.07999932707309
}
},
"distance": {
"value": 46718.8049,
"metric": "METERS",
"unit": "m",
"normalizedValue": 0.00732483559070619
}
},
{
"content": {
"name": "gaoyi",
"point": {
"x": 114.55999821424484,
"y": 37.62000066579741
}
},
"distance": {
"value": 56752.5152,
"metric": "METERS",
"unit": "m",
"normalizedValue": 0.00889797682301274
}
}
]
}
}Response code: 200; Time: 92ms; Content length: 1844 bytes
上傳的只是練習(xí)項(xiàng)目,同理只需要將城市名稱換成職業(yè)id即可
到此這篇關(guān)于Redis GEO實(shí)現(xiàn)附近搜索功能的文章就介紹到這了,更多相關(guān)Redis GEO附近搜索內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
RedisTemplate訪問(wèn)Redis的更好方法
這篇文章主要為大家介紹了RedisTemplate訪問(wèn)Redis的更好方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01springboot +redis 實(shí)現(xiàn)點(diǎn)贊、瀏覽、收藏、評(píng)論等數(shù)量的增減操作
這篇文章主要介紹了springboot +redis 實(shí)現(xiàn)點(diǎn)贊、瀏覽、收藏、評(píng)論等數(shù)量的增減操作,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09使用Redis實(shí)現(xiàn)記錄訪問(wèn)次數(shù)的三種方案
這篇文章主要介紹了使用Redis實(shí)現(xiàn)記錄訪問(wèn)次數(shù)的三種方案,文中通過(guò)代碼示例和圖文講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-09-09Redis字典實(shí)現(xiàn)、Hash鍵沖突及漸進(jìn)式rehash詳解
這篇文章主要介紹了Redis字典實(shí)現(xiàn)、Hash鍵沖突以及漸進(jìn)式rehash的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09淺談redis采用不同內(nèi)存分配器tcmalloc和jemalloc
下面小編就為大家?guī)?lái)一篇淺談redis采用不同內(nèi)存分配器tcmalloc和jemalloc。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12redis與memcached的區(qū)別_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
Memcached是以LiveJurnal旗下Danga Interactive公司的Bard Fitzpatric為首開發(fā)的高性能分布式內(nèi)存緩存服務(wù)器。那么redis與memcached有什么區(qū)別呢?下面小編給大家介紹下redis與memcached的區(qū)別,感興趣的朋友參考下吧2017-08-08Redis Cluster集群動(dòng)態(tài)擴(kuò)容的實(shí)現(xiàn)
本文主要介紹了Redis Cluster集群動(dòng)態(tài)擴(kuò)容的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07