二刷 黑馬點評 附近商戶

附近商戶-GEO數據結構的基本用法

GEO就是Geolocation的簡寫形式,代表地理坐標
Redis在3.2版本中加入了對GEO的支持,允許存儲地理坐標信息,幫助我們根據經緯度來檢索數據。常見的命令有:

  • GEOADD:添加一個地理空間信息,包含:經度(longitude)、緯度(latitude)、值(member)

  • GEODIST:計算指定的兩個點之間的距離并返回

  • GEOHASH:將指定member的坐標轉為hash字符串形式并返回

  • GEOPOS:返回指定member的坐標

  • GEORADIUS:指定圓心、半徑,找到該圓內包含的所有member,并按照與圓心之間的距離排序后返回。6.以后已廢棄

  • GEOSEARCH:在指定范圍內搜索member,并按照與指定點之間的距離排序后返回。范圍可以是圓形或矩形。6.2.新功能

  • GEOSEARCHSTORE:與GEOSEARCH功能一致,不過可以把結果存儲到一個指定的key。 6.2.新功能

導入店鋪數據到GEO

![[Pasted image 20250718204058.png]]

當我們點擊美食之后,會出現一系列的商家,商家中可以按照多種排序方式,我們此時關注的是距離,這個地方就需要使用到我們的GEO,向后臺傳入當前app收集的地址(我們此處是寫死的) ,以當前坐標作為圓心,同時綁定相同的店家類型type,以及分頁信息,把這幾個條件傳入后臺,后臺查詢出對應的數據再返回。

我們把x軸坐標和y軸坐標當作score傳入到redis中,不要把所有數據都放到redis
同時把商戶類型做分類,相同類型的商戶作為一組,放入同一個GEO集合中
![[Pasted image 20250718204424.png]]

@Test
void loadShopData() {// 1.查詢店鋪信息List<Shop> list = shopService.list();// 2.把店鋪分組,按照typeId分組,typeId一致的放到一個集合Map<Long, List<Shop>> map = list.stream().collect(Collectors.groupingBy(Shop::getTypeId));// 3.分批完成寫入Redisfor (Map.Entry<Long, List<Shop>> entry : map.entrySet()) {// 3.1.獲取類型idLong typeId = entry.getKey();String key = SHOP_GEO_KEY + typeId;// 3.2.獲取同類型的店鋪的集合List<Shop> value = entry.getValue();List<RedisGeoCommands.GeoLocation<String>> locations = new ArrayList<>(value.size());// 3.3.寫入redis GEOADD key 經度 緯度 memberfor (Shop shop : value) {// stringRedisTemplate.opsForGeo().add(key, new Point(shop.getX(), shop.getY()), shop.getId().toString());locations.add(new RedisGeoCommands.GeoLocation<>(shop.getId().toString(),new Point(shop.getX(), shop.getY())));}stringRedisTemplate.opsForGeo().add(key, locations);}
}

先查詢店鋪信息,從數據庫中獲取所有店鋪的信息,并將其存儲到List類型的變量list中
按店鋪類型分組,利用Stream API ,代碼將獲取的店鋪列表按typeId分組,相同typeId的店鋪會被歸于同一個列表,最終形成Map<Long,List>類型的映射map,其中鍵是typeId,值是對應類型的店鋪列表。
對于每個類型的店鋪,先獲取當前類型的typeId,創建對應的Redis Key值
對于每個店鋪,創建一個RedisGeoCommands.GeoLocation對象,包括店鋪ID、經緯度等
將所有對象收集到一個列表,最后通過opsForGeo()批量寫入redis

附近商戶-實現附近商戶功能

   // 1.判斷是否需要根據坐標查詢if (x == null || y == null) {// 不需要坐標查詢,按數據庫查詢Page<Shop> page = query().eq("type_id", typeId).page(new Page<>(current, SystemConstants.DEFAULT_PAGE_SIZE));// 返回數據return Result.ok(page.getRecords());}

先看有沒有傳坐標,沒有直接按數據庫查詢

    // 3.查詢redis、按照距離排序、分頁。結果:shopId、distanceString key = SHOP_GEO_KEY + typeId;GeoResults<RedisGeoCommands.GeoLocation<String>> results = stringRedisTemplate.opsForGeo() // GEOSEARCH key BYLONLAT x y BYRADIUS 10 WITHDISTANCE.search(key,GeoReference.fromCoordinate(x, y),new Distance(5000),RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs().includeDistance().limit(end));

若傳輸了坐標,就按距離排序后分頁

  • stringRedisTemplate.opsForGeo().search()調用 Redis 的 GEOSEARCH 命令。
  • key:指定要搜索的地理位置數據集合。
  • GeoReference.fromCoordinate(x, y):指定中心點坐標。
  • new Distance(5000):設置搜索半徑為 5000 米。
  • includeDistance().limit(end):要求返回距離信息,并限制最多返回end條結果。
 List<Long> ids = new ArrayList<>(list.size());Map<String, Distance> distanceMap = new HashMap<>(list.size());list.stream().skip(from).forEach(result -> {// 4.2.獲取店鋪idString shopIdStr = result.getContent().getName();ids.add(Long.valueOf(shopIdStr));// 4.3.獲取距離Distance distance = result.getDistance();distanceMap.put(shopIdStr, distance);});

創建ids列表存放店鋪ID
常見distanceMap存儲店鋪ID和距離的映射關系
借助流中的skip(from)跳過前from個元素
然后對于每個元素獲取店鋪id和距離,添加到ids和distanceMap中

    // 5.根據id查詢ShopString idStr = StrUtil.join(",", ids);List<Shop> shops = query().in("id", ids).last("ORDER BY FIELD(id," + idStr + ")").list();for (Shop shop : shops) {shop.setDistance(distanceMap.get(shop.getId().toString()).getValue());}// 6.返回return Result.ok(shops);

將ids拼成字符串然后通過mybatis-plus提供的數據庫查詢操作得到店鋪,對于每一個店鋪,利用之前得到的distanceMap將位置信息賦值

總結

  1. Redis GEO 數據結構在 “附近商戶” 功能中核心作用是什么?
    Redis GEO 用于存儲地理坐標信息(經度、緯度),并提供高效的地理位置查詢能力(如范圍搜索、距離計算),是實現 “按距離篩選附近商戶” 功能的核心存儲與查詢工具。
  2. 商戶數據導入 Redis GEO 的關鍵步驟是什么?
    核心步驟包括:①從數據庫查詢所有商戶信息;②按商戶類型(typeId)分組,確保同類型商戶聚合;③將每組商戶的經緯度、ID 封裝為 GEO 坐標對象,批量寫入對應類型的 Redis GEO 集合(通過GEOADD命令)。
  3. 實現 “附近商戶” 查詢的核心流程是什么?
    ①接收用戶當前坐標、商戶類型、分頁參數;②通過 Redis GEO 的GEOSEARCH命令,以用戶坐標為中心,按指定半徑查詢目標類型商戶的 ID 及距離;③根據 ID 從數據庫查詢商戶詳細信息,并關聯 Redis 返回的距離數據;④返回帶距離的商戶列表。
  4. 為何要按商戶類型分組存儲 GEO 數據?
    按類型分組可縮小查詢范圍,避免無關類型商戶參與計算,提升GEOSEARCH命令的執行效率;同時符合用戶 “按類型找商戶” 的實際業務場景,減少無效數據處理。
  5. 如何保證查詢結果中 “距離” 信息的準確性?
    Redis GEO 在范圍查詢時通過includeDistance參數返回商戶與中心點的距離,查詢后將該距離與數據庫查詢的商戶信息一一映射(通過商戶 ID 關聯),確保距離與商戶信息精準匹配。

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

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

相關文章

【vue-3】深入理解 Vue 3 中的 v-if 指令:條件渲染的藝術

在 Vue.js 的世界中&#xff0c;條件渲染是構建動態界面的核心概念之一。作為 Vue 3 中最常用的指令之一&#xff0c;v-if 提供了強大的能力來控制元素的顯示與隱藏。本文將深入探討 v-if 的工作原理、最佳實踐以及它在 Vue 3 中的新特性。 1. 什么是 v-if&#xff1f; v-if 是…

【實時Linux實戰系列】實時系統中的內存策略

在實時系統中&#xff0c;內存管理是確保系統性能和穩定性的重要組成部分。實時系統通常需要快速響應和低延遲&#xff0c;因此高效的內存管理策略對于實現這些目標至關重要。實時 Linux 提供了多種內存管理機制&#xff0c;如使用大型頁面&#xff08;Huge Pages&#xff09;和…

【C語言進階】題目練習(2)

目錄 題目6:看代碼說結果 分析&#xff1a; 答案&#xff1a;255 題目7&#xff1a;猜名次 分析&#xff1a; 題目8&#xff1a;猜兇手 分析&#xff1a; 代碼&#xff1a; 題目9&#xff1a;打印楊輝三角 思路: 代碼: 題目10&#xff1a;關于指針的選擇題 答案&a…

思科NAT綜合實驗

1 實驗拓撲圖2實驗目的(1)鞏固前面實驗的配置(2)掌握四種NAT的配置(3)明白四種NAT的區別3實驗步驟3.1配置邊界路由器和外網路由器的端口IP三個步驟&#xff1a;進入端口 打開端口 配置IP地址和子網掩碼interface f0/0 no shutdown ip address 192.168.201.2 255.255.255.03.2配…

VMC850立式加工中心Y軸傳動機械結構設計cad【7張】三維圖+設計說明書

摘 要 數控機床作為現代工業生產的重要設備&#xff0c;對國民經濟的發展有著重要的作用&#xff0c;立式加工中心作為數控加工技術的核心&#xff0c;通過對其研究&#xff0c;可以深入了解數控技術未來的發展方向。本文主要完成了VMC850立式加工中心Y軸的機械傳動結構設計&am…

mpiigaze的安裝過程一

mpiigaze鏈接 mpiigaze應該不是作者本人寫的&#xff0c;而是社區工作者的杰作&#xff0c;對原論文Appearance-Based Gaze Estimation in the Wild的代碼進行的一些復現 1.創建conda環境 2.問題 Building wheels for collected packages: dlibBuilding wheel for dlib (py…

如何將華為文件傳輸到電腦

在數字管理領域&#xff0c;將華為設備上的文件傳輸到電腦是高頻需求。無論為了備份、緩解手機存儲壓力&#xff0c;還是跨平臺訪問&#xff0c;把華為手機連接電腦已成為許多用戶的剛需。下面介紹 5 種高效方法&#xff0c;可滿足不同場景與偏好&#xff0c;助你輕松完成文件遷…

LP-MSPM0G3507學習--05中斷及管腳中斷

關鍵函數&#xff1a; NVIC_EnableIRQ(IRQn_Type IRQn)&#xff1a;使能中斷 例5-1&#xff1a;單按鍵中斷方式實現led燈的亮滅 在上一講LP-MSPM0G3507學習--04GPIO控制中實現了通過按鍵控制led燈的亮滅&#xff0c;可以看出程序效率不高&#xff0c;下面采用中斷的方式實現…

mac系統安裝、啟動Jenkins,創建pytest接口自動化任務

先安裝Homebrew&#xff1a;mac系統安裝brew-CSDN博客 1、安裝Jenkins # 可以安裝長期支持版本 brew install jenkins-lts# 或者最新版本&#xff08;我安了這個&#xff09; brew install jenkins 可查看Jenkins安裝位置&#xff1a; # 最新版本 brew --prefix jenkins 2、…

設置第三方窗口置頂(SetWindowPos方法,vb.net)

起源在日常辦公、游戲時&#xff0c;我們經常需要一些窗口處于置頂狀態&#xff0c;而這些窗口往往是網頁端&#xff08;瀏覽器&#xff09;、辦公軟件&#xff08;wps、office等&#xff09;&#xff0c;這些需要置頂的窗口往往自身沒有明顯的置頂開關&#xff0c;因此&#x…

Docker-下載和安裝

一、Linux版 1.安裝docker &#xff08;1&#xff09;更新軟件包索引 sudo apt update &#xff08;2&#xff09;安裝必要的依賴 sudo apt install apt-transport-https ca-certificates curl software-properties-common &#xff08;3&#xff09;添加 Docker 官方 GP…

電腦DLL錯誤修復dll微軟運行庫工具修復dll缺失找不到dll等問題,dll免費修復工具

解決DLL文件缺失問題&#xff1a;我的使用體驗與建議 在使用電腦的過程中&#xff0c;我們常常會遇到軟件或系統報錯&#xff0c;例如“無法找到指定模塊”或“缺少某.dll文件”等提示。DLL&#xff08;動態鏈接庫&#xff09;是Windows系統中不可或缺的組件&#xff0c;為應用…

HTTPS的工作原理及DNS的工作過程

HTTPSHTTP協議安全上存在以下三個風險&#xff1a;完整性 可用性 保密性竊聽風險&#xff0c;比如通信鏈路上可以獲取通信內容&#xff0c;用戶號容易沒。篡改風險&#xff0c;比如強制植入垃圾廣告&#xff0c;視覺污染&#xff0c;用戶眼容易瞎。冒充風險&#xff0c;比如冒充…

VisualXML全新升級 | 新增BusLoad計算

VisualXML是一個功能強大的網絡總線設計工具&#xff0c;專注于簡化汽車電子系統中復雜的網絡數據設計操作。該軟件支持多種主流總線網絡格式的數據編輯&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能夠基于Excel表格的方式生成和轉換多種數據庫文件。由此…

李天意考研數學精講課學習筆記(課堂版)

視頻鏈接&#xff1a;【考研數學精講課李天意】基礎強化真題&#xff0c;概念精講與解題技巧&#xff08;適用數學一/二/三&#xff09;_嗶哩嗶哩_bilibili 講義&#xff1a;夸克網盤分享 高數6 不定積分

閑庭信步使用圖像驗證平臺加速FPGA的開發:第二十三課——圖像直方圖和灰度圖像疊加的FPGA實現

&#xff08;本系列只需要modelsim即可完成數字圖像的處理&#xff0c;每個工程都搭建了全自動化的仿真環境&#xff0c;只需要雙擊top_tb.bat文件就可以完成整個的仿真&#xff0c;大大降低了初學者的門檻&#xff01;&#xff01;&#xff01;&#xff01;如需要該系列的工程…

C++并發編程-14. 利用柵欄實現同步

前文我們通過原子操作實戰實現了無鎖隊列&#xff0c;今天完善一下無鎖的原子操作剩余的知識&#xff0c;包括Relaese和Acquire內存序在什么情況下是存在危險的&#xff0c;以及我們可以利用柵欄機制實現同步等等。 線程可見順序 我們提到過除了memory_order_seq_cst順序&#…

如何選擇旅游科技行業云ERP?Oracle NetSuite助力匯智國際數智化升級

2025年4月21日&#xff0c;匯智國際旅游發展有限公司&#xff08;以下簡稱匯智國際&#xff09;攜手 Oracle NetSuite與Hitpoint Cloud &#xff0c;共同參與了匯智國際 Oracle NetSuite 云ERP 項目啟動會。 本次會議標志著匯智國際在數字化轉型道路上邁出了堅實而關鍵的一步&…

深度學習零基礎入門(3)-圖像與神經網絡

好久不見~我又回來了 這一節我們來講一講圖像在計算機中的本質&#xff0c;以及全連接神經網絡的缺陷&#xff0c;進而引出卷積神經網絡一、圖像在計算機中的本質 不知道你有沒有學過數據結構&#xff0c;在講這一部分的時候對數組進行了擴展&#xff0c;講到了廣義表和壓縮矩陣…

http性能測試命令ab

在 Linux系統中&#xff0c; ab&#xff08; ApacheBench&#xff09;是一個用于 測試HTTP服務器性能的 工具。它是 Apache HTTP服務器項目的 一部分&#xff0c;專門設計用來模擬 多個用戶對 服務器發起 并發請求&#xff0c;從而 評估服務器的 負載能力和 響應時間其中&#…