如何在項目當中使用redis進行范圍搜索

目錄

?

如何將地理位置數據保存到 Redis 中以支持范圍查詢

Redis 中的 GEO 類型是什么?

如何保存 GEO 數據到 Redis?

分段解釋:?

RedisKey.POSTS_ANIMALS_LOCATIONS

new Point(longitude, latitude)

?

如何進行范圍搜索

Redis GEO 范圍搜索核心語句

1.redisTemplate.opsForGeo().search(...)

2. RedisKey.POSTS_ANIMALS_LOCATIONS

3. GeoReference.fromCoordinate(x, y)

4. new Distance(5000)

5. RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs()

6. .includeDistance()

搜索結果判空

提取 Redis 搜索結果?


?

如何將地理位置數據保存到 Redis 中以支持范圍查詢

Redis 中的 GEO 類型是什么?

Redis 提供了 GEO 命令支持地理位置信息的存儲和查詢,底層使用 Geohash 編碼 + Sorted Set(有序集合) 實現。你可以對其進行:

  • 添加坐標(經緯度);

  • 查詢指定位置一定范圍內的成員;

  • 獲取兩個成員之間的距離;

  • 查詢某個成員的位置等。

如何保存 GEO 數據到 Redis?

redisTemplate.opsForGeo().add(RedisKey.POSTS_ANIMALS_LOCATIONS, // Redis 中的 key,用來存所有帖子的位置new Point(animalsRescueDTO.getLongitude(), animalsRescueDTO.getLatitude()), // 經緯度(Point 構造順序:經度, 緯度)posts.getPostId().toString() // 這個帖子的位置用帖子 ID 作為唯一標識(member)
);

?

👇 實際等價于 Redis 命令:?

GEOADD POSTS_ANIMALS_LOCATIONS 113.1234 23.5678 "123"
  • POSTS_ANIMALS_LOCATIONS 是存儲地理數據的 Redis 鍵

  • 113.1234 是經度(longitude)

  • 23.5678 是緯度(latitude)

  • "123" 是帖子 ID(即你 posts.getPostId()

分段解釋:?

redisTemplate.opsForGeo()

這是 Spring Data Redis 提供的模板方法,用于執行 GEO 類型操作 的入口。

它返回的是一個 GeoOperations<K, V> 對象,可以執行下面這些操作:

方法功能
add(...)添加地理位置點(經度、緯度 + 名稱)
search(...)按照范圍搜索附近的點
distance(...)計算兩個點之間的距離
position(...)獲取某個 member 的坐標
hash(...)獲取某個 member 的 geohash 值

RedisKey.POSTS_ANIMALS_LOCATIONS

這是一個 Redis 的 Key,表示你所有帖子位置都保存在這個 key 下的 GEO 類型中。

?

new Point(longitude, latitude)

這是一個 Spring 提供的 org.springframework.data.geo.Point 類型,用于封裝經緯度。

?? 注意順序:

Point(x, y) 中,x 是經度y 是緯度

?

Redis 是使用底層的 ZSet + Geohash 來實現這個數據結構的:

  • 每個點會被編碼成 geohash,對應 ZSet 的 score

  • 可以用 ZRANGEGEORADIUS 等方式高效查詢范圍

?

如何進行范圍搜索

Redis GEO 范圍搜索核心語句

GeoResults<RedisGeoCommands.GeoLocation<String>> results = redisTemplate.opsForGeo().search(RedisKey.POSTS_ANIMALS_LOCATIONS, // Redis 中 GEO 數據所在的 keyGeoReference.fromCoordinate(x, y), // 查詢圓心:經度 x,緯度 ynew Distance(5000),                // 查詢半徑:5000 米(5 公里)RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs().includeDistance()             // 查詢結果中返回每個點的距離
);
參數類型說明
keyStringRedis 中存儲 GEO 數據的 key,也就是你存儲地理數據時使用的那個 key。例如你之前可能使用 RedisKey.POSTS_ANIMALS_LOCATIONS 存儲了所有帖子的地理位置信息。
geoReferenceGeoReference查詢圓心坐標(經緯度)。這代表你要查詢的中心點的位置。
distanceDistance查詢的范圍半徑,單位是米(m),表示你想要查詢中心點 geoReference 周圍多少米以內的所有地理位置。
argsGeoSearchCommandArgs查詢參數的設置,可以設置排序、返回距離等額外選項。

?

1.redisTemplate.opsForGeo().search(...)

  • opsForGeo():Spring Data Redis 提供的 GEO 操作 API

  • search(...):封裝了 Redis 6.2+ 的 GEOSEARCH 命令,是范圍查找的入口

2. RedisKey.POSTS_ANIMALS_LOCATIONS

  • 這是 Redis 中用于保存 GEO 數據的鍵名(key)

  • 對應 Redis 的底層命令示例:

?

3. GeoReference.fromCoordinate(x, y)

這是查詢的中心點:

GeoReference.fromCoordinate(double longitude, double latitude)

注意順序是:

經度在前(x)緯度在后(y)

這個代表:

“我現在的位置是 (經度, 緯度),請查我附近的 member”

你傳入的 (x, y) 一般來源于用戶定位(如小程序的 wx.getLocation()

?

4. new Distance(5000)

  • Distance 是 Spring 提供的距離對象

  • 默認單位是 米(Meters)

  • 所以這是一個 以中心點為圓心、半徑為 5000 米(5 公里) 的范圍查找

?

5. RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs()

這是搜索的“附加參數”,你可以在里面設置返回什么信息、是否排序、返回幾個等。

是一個“無參的靜態方法”,作用是:

返回一個新的 GeoSearchCommandArgs 對象,用來配置 Redis GEO 查詢參數。

你得到了一個 GeoSearchCommandArgs 類型的對象,后面可以繼續鏈式調用:

舉例:

RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs()
.includeDistance().limit(5).sortAscending();

?

6. .includeDistance()

這個非常重要!

  • 它的作用是:讓返回結果中附帶每個點距離圓心的“實際距離”

  • 否則默認只返回哪些 member 在范圍內,不告訴你它們距離多遠

搜索結果判空

if (results == null || results.getContent().isEmpty()) {return nearbyRescues;  // 無結果,直接返回空列表
}

?

提取 Redis 搜索結果?

Map<Integer, Distance> distanceMap = new HashMap<>();
List<Integer> ids = new ArrayList<>();for (GeoResult<RedisGeoCommands.GeoLocation<String>> location : results.getContent()) {Integer postId = Integer.valueOf(location.getContent().getName());Distance distance = location.getDistance();ids.add(postId);distanceMap.put(postId, distance);
}

?

?

👉 這里構建:

  • ids:用于批量查數據庫

  • distanceMap:用于后續給每個 PostsVo 設置距離屬性

GeoResults
└── getContent() → List<GeoResult>└── GeoResult├── getContent() → GeoLocation│    ├── getName() → 帖子ID("123")│    └── getPoint() → 經緯度└── getDistance() → 到查詢中心的距離

🔹 每個 GeoResult 里包含:

  • .getName() → Redis GEO 中的 member(這里是帖子 ID),實際就是 Redis GEO 中的 member

  • .getDistance() → 距離圓心的距離

GeoResults<GeoLocation<String>> results = {List<GeoResult<GeoLocation<String>>> content = [GeoResult {content: GeoLocation {name: "123",                    // member → 帖子IDpoint: Point(113.2345, 23.4567) // 坐標},distance: Distance(4213.5)         // 到查詢點的距離(單位米)},GeoResult {content: GeoLocation {name: "124",point: Point(...)},distance: ...},...]
}

完整范圍搜索的例子

@Override@Transactionalpublic ArrayList<PostsVo> getNearbyRescue(double y, double x) {GeoResults<RedisGeoCommands.GeoLocation<String>> results = redisTemplate.opsForGeo().search(RedisKey.POSTS_ANIMALS_LOCATIONS,                                       // Redis 中存儲地理位置數據的鍵GeoReference.fromCoordinate(x, y),        // 查詢的圓心坐標 (經度, 緯度)new Distance(5000),                       // 查詢的半徑范圍為 5000 米(5 公里)RedisGeoCommands.GeoSearchCommandArgs     // 額外的查詢參數.newGeoSearchArgs().includeDistance()                    // 返回結果中包含距離);//一系列的封裝返回前端的操作ArrayList<PostsVo> nearbyRescues = new ArrayList<>();// 檢查查詢是否有結果if (results == null || results.getContent().isEmpty()) {return nearbyRescues;  // 沒有找到附近的帖子,返回空列表}// 用于存儲 postId 和其對應的 DistanceMap<Integer, Distance> distanceMap = new HashMap<>();List<Integer> ids = new ArrayList<>();// 遍歷 Geo 結果,提取 postId 和 distancefor (GeoResult<RedisGeoCommands.GeoLocation<String>> location : results.getContent()) {Integer postId = Integer.valueOf(location.getContent().getName());Distance distance = location.getDistance();ids.add(postId);distanceMap.put(postId, distance);}// 批量查詢 postsList<Posts> postsList = postsMapper.selectBatchIds(ids);// 轉換為 PostsVo 并將距離賦值進去nearbyRescues = postsList.stream().map(post -> {PostsVo postsVo = BeanUtil.copyProperties(post, PostsVo.class);// 假設 posts 對象中有 getPostId() 方法獲取 idDistance d = distanceMap.get(post.getPostId());if(d != null){// 將距離單位轉換為公里(如果需要),這里假設 d.getValue() 返回的是米postsVo.setDistance(d.getValue() / 1000.0);}// 根據animalId查詢動物信息Animals animals = animalsMapper.selectById(post.getAnimalId());AnimalsVo animalsVo = BeanUtil.copyProperties(animals, AnimalsVo.class);String[] photos = animals.getPhotos().split(",");animalsVo.setPhotos(photos);postsVo.setAnimalsVo(animalsVo);return postsVo;}).collect(Collectors.toCollection(ArrayList::new));return nearbyRescues;}

Redis GEO 本質上是在 Redis 中保存地理位置數據(使用經緯度 + key + member 的形式),然后通過 GEORADIUS / GEOSEARCH 實現地理范圍搜索。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82153.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82153.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82153.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

物聯網低功耗保活協同優化方案:軟硬件與WiFi網關動態聯動

目錄 一、總體方案概述 二、架構組成 2.1 系統拓撲 2.2 硬件端(MCU + WiFi 模組) 2.3 WiFi 網關 2.4 云端服務器 三、低功耗保活技術設計模式 3.1 模式一:定時喚醒 + MQTT 保活 3.1.1 設備端 3.1.2 優勢 3.2 模式二:網關保活代理 + 本地網絡喚醒 3.2.1 網關功能…

UniApp+Vue3微信小程序二維碼生成、轉圖片、截圖保存整頁

二維碼生成工具使用uqrcode/js&#xff0c;版本4.0.7 官網地址&#xff1a;uQRCode 中文文檔&#xff08;不建議看可能會被誤導&#xff09; 本項目采用了npm引入方式&#xff0c;也可通過插件市場引入&#xff0c;使用上會略有不同 準備工作&#xff1a; 安裝&#xff1a;pnpm…

Zenmap代理情況下無法掃描ip

原因是開了代理會報錯 error “only ethernet devices can be used for raw scans on Windows” 在掃描參數后加 -sT -Pn&#xff0c;但會導致結果太多 例如&#xff1a;nmap -sT -T4 -A -v -Pn 10.44.2.0/24 如果你只是想找沒人用的IP&#xff0c;你不需要搞復雜的原始層掃描&…

將多個值關聯到同一個 key的map(key可以重復的map)示例

在 Java 中&#xff0c;標準的 Map 接口要求 key 必須唯一&#xff0c;如果需要 key 可重復 且保持 插入順序 的數據結構&#xff0c;可以使用以下方案&#xff1a; 1. 使用 List<Map.Entry<K, V>> 最直接的方式是用鏈表存儲鍵值對&#xff0c;允許重復 key&…

Arthas(阿爾薩斯)

一、Arthas 是什么&#xff1f; Arthas&#xff08;阿爾薩斯&#xff09;是阿里巴巴開源的一款 Java 在線診斷工具&#xff0c;基于 Java Agent 和字節碼增強技術實現。它無需重啟 JVM&#xff0c;即可動態追蹤代碼執行、實時查看 JVM 狀態、修改代碼邏輯&#xff0c;是生產環…

深入解讀Qwen3技術報告(三):深入剖析Qwen3模型架構

重磅推薦專欄&#xff1a; 《大模型AIGC》 《課程大綱》 《知識星球》 本專欄致力于探索和討論當今最前沿的技術趨勢和應用領域&#xff0c;包括但不限于ChatGPT和Stable Diffusion等。我們將深入研究大型模型的開發和應用&#xff0c;以及與之相關的人工智能生成內容&#xff…

UE4游戲查找本地角色數據的方法-SDK

UE4中&#xff0c;玩家的表示通常涉及以下幾個類&#xff1a; APlayerController: 代表玩家的控制邏輯&#xff0c;處理輸入等。 APawn: 代表玩家在世界中的實體&#xff08;比如一個角色、一輛車&#xff09;。APlayerController 控制一個 APawn。 ACharacter: APawn 的一個…

springboot+vue實現服裝商城系統(帶用戶協同過濾個性化推薦算法)

今天教大家如何設計一個服裝商城 , 基于目前主流的技術&#xff1a;前端vue3&#xff0c;后端springboot。 同時還帶來的項目的部署教程。 系統最大的亮點是使用了兩個推薦算法: 1. 基于Jaccard算法的用戶瀏覽歷史推薦。 2. 基于用戶的協同過濾算法個性化推薦。 還有核心的商…

ERROR: Could not install packages due to an OSError: [WinError 5] 拒絕訪問

有可能是設置了代理 unset ALLPROXY 或者注釋掉 當然也有可能是其他原因 權限不足?? 以管理員身份運行 CMD/PowerShell&#xff0c;或使用 --user 安裝 ??文件被占用?? 關閉殺毒軟件或重啟電腦 Python 環境損壞?? 重新安裝 Python 或使用虛擬環境 ?? 殺毒軟件阻止…

【深尚想!愛普特APT32F1023H8S6單片機重構智能電機控制新標桿】

在智能家電與健康器械市場爆發的今天&#xff0c;核心驅動技術正成為產品突圍的關鍵。傳統電機控制方案面臨集成度低、開發周期長、性能瓶頸三大痛點&#xff0c;而愛普特電子帶來的APT32F1023H8S6單片機無感三合一方案&#xff0c;正在掀起一場智能電機控制的技術革命。 爆款基…

一個.NET開源、輕量級的運行耗時統計庫

前言 在.NET開發中&#xff0c;為了準確統計對應方法的執行時間&#xff0c;我們最常用的方式是手動使用 Stopwatch 來顯式編寫計時邏輯&#xff0c;但是假如你需要大量的使用 Stopwatch 來進行耗時統計的話不利于保持代碼的整潔和增加代碼的維護成本。 項目介紹 MethodTime…

嵌入式鴻蒙openharmony應用開發環境搭建與工程創建實現

各位小伙伴大家好,本周開始分享鴻蒙開發相關的內容,從基礎的配置方法到各種功能的實現,探索國產操作系統的奧秘。 第一:觀察結果 第二:開源語言 ArkTS是鴻蒙應用開發中使用的TypeScript超集,提供了一套豐富的API來構建應用界面和邏輯。 第三:環境搭建 步驟 1 通過如…

軟考 組合設計模式

組合設計模式&#xff08;Composite Pattern&#xff09;是結構型設計模式之一&#xff0c;它的核心思想是將對象組合成樹形結構來表示“部分-整體”的層次結構&#xff0c;使得用戶對單個對象和組合對象的使用具有一致性。 主要概念&#xff1a; 組件&#xff08;Component&a…

vue 中的v-once

&#x1f530; 基礎理解 ? 語法&#xff1a; <span v-once>{{ msg }}</span>? 效果&#xff1a; ? 只渲染一次&#xff0c;之后無論數據如何變化&#xff0c;該內容都不會更新。 ? 非常適用于靜態內容或首次加載后不需要變化的數據。&#x1f9ea; 示例&…

GPU訓練和call方法

知識點回歸: CPU性能的查看:看架構代際、核心數、線程數GPU性能的查看:看顯存、看級別、看架構代際GPU訓練的方法:數據和模型移動到GPU device上類的call方法:為什么定義前向傳播時可以直接寫作self.fc1(x)import torch import torch.nn as nn import torch.optim as opti…

人臉識別備案開啟安全防護模式!緊跟《辦法》!

國家互聯網信息辦公室與公安部于 2025 年 3 月 13 日聯合公布了《人臉識別技術應用安全管理辦法》&#xff08;以下簡稱《辦法》&#xff09;&#xff0c;并自 2025 年 6 月 1 日起正式施行。其中&#xff0c;人臉識別備案成為了規范技術應用、守護信息安全的關鍵一環。? 一、…

LeetCode:貪心算法

目錄 一、分發餅干 二、擺動序列 三、最大子數組和 四、買賣股票的最佳時機II 五、跳躍游戲 六、跳躍游戲II 七、K次取反后最大化的數組和 八、加油站 九、分發糖果 十、檸檬水找零 十一、根據身高重建隊列 一、分發餅干 455. 分發餅干 - 力扣&#xff08;LeetCode…

企業級 Hosts 自動化管理實戰:基于 HTTP 檢測的高可用域名解析方案

摘要 本文針對企業級域名解析穩定性需求&#xff0c;提供一套從IP 檢測到Hosts 更新的完整自動化解決方案。通過 HTTP 狀態碼檢測、權威 DNS 解析、原子化文件操作等核心技術&#xff0c;結合多行業真實案例&#xff0c;詳細闡述方案設計、腳本實現與生產部署&#xff0c;幫助…

基于springboot+vue網頁系統的社區義工服務互動平臺(源碼+論文+講解+部署+調試+售后)

感興趣的可以先收藏起來&#xff0c;還有大家在畢設選題&#xff0c;項目以及論文編寫等相關問題都可以給我留言咨詢&#xff0c;我會一一回復&#xff0c;希望幫助更多的人。 系統背景 在社會文明程度不斷提升、社區治理需求持續深化的大背景下&#xff0c;社區義工服務作為…

從細胞工廠到智能制造:Extracellular 用時序數據庫 TDengine 打通數據生命線

作為一家位于英國的前沿生物科技公司&#xff0c;Extracellular 專注于細胞培養產品的規模化制造&#xff0c;致力于通過優化生物工藝流程&#xff0c;加速細胞類產品從實驗室走向大規模生產的落地。為了實現這一目標&#xff0c;他們需要一個穩定、高效、可擴展的數據平臺&…