欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Redis實現(xiàn)附近商鋪查詢功能

 更新時間:2025年05月09日 14:21:48   作者:編程學(xué)委  
這篇文章主要介紹了基于Redis實現(xiàn)-附近商鋪查詢功能,這個功能將使用到Redis中的GEO這種數(shù)據(jù)結(jié)構(gòu)來實現(xiàn),需要的朋友可以參考下

基于Redis實現(xiàn)-附近查詢

這個功能將使用到Redis中的GEO這種數(shù)據(jù)結(jié)構(gòu)來實現(xiàn)。

1.GEO相關(guān)命令

GEO就是Geolocation的簡寫形式,代表地理坐標(biāo)。Redis在3.2版本中加入到了對GEO的支持,允許存儲地理坐標(biāo)信息,幫助我們根據(jù)經(jīng)緯度來檢索數(shù)據(jù),常見命令如下:

  • GEOADD: 添加一個地理空間信息,包含:經(jīng)度(longitude)、緯度(latitude)、值(member)
  • GEODIST: 計算指定的兩個點之間的距離并返回
  • GEOHASH: 將指定member的坐標(biāo)轉(zhuǎn)為hash字符串形式并返回
  • GEOPOS: 返回指定member的坐標(biāo)
  • GEORADIUS: 指定圓心、半徑,找到該圓內(nèi)包含的所有member,并按照與圓心之間的距離排序后返回。6.2以后已廢棄
  • GEOSEARCH: 在指定范圍內(nèi)搜索member,并按照與指定點之間的距離排序后返回。范圍可以是圓形或矩形。6.2.新功能
  • GEOSEARCHSTORE: 與GEOSEARCH功能一致,不過可以把結(jié)果存儲到一個指定的key。6.2.新功能

2.使用GEO來實現(xiàn)以下功能

添加下面幾條數(shù)據(jù):

  • 北京南站(116.378248 39.865275)
  • 北京站(116.42803 39.903738)
  • 北京西站(116.322287 39.893729)
# 1. 添加地理空間數(shù)據(jù)
GEOADD stations 116.378248 39.865275 "北京南站" 116.42803 39.903738 "北京站" 116.322287 39.893729 "北京西站"

計算北京西站到北京站的距離

# 2. 計算北京西站到北京站的距離
GEODIST stations "北京西站" "北京站" km

搜索天安門(116.397904 39.909005)附近10km內(nèi)的所有火車站,并按照距離升序排序

# 3. 搜索天安門附近10km內(nèi)的火車站并按距離排序
GEOSEARCH stations FROMLONLAT 116.397904 39.909005 BYRADIUS 10 km ASC

3.使用Java實現(xiàn)簡單的附近商鋪查詢

//在ServiceImpl中(簡單演示)
@Autowired
    private StringRedisTemplate stringRedisTemplate;
@Override
public Result queryShopByType(Integer typeId, Integer current, Double x, Double y) {
    // 1. 判斷是否需要基于地理位置查詢
    if (x == null || y == null) {
        // 不需要地理坐標(biāo)查詢時,直接按類型分頁查詢數(shù)據(jù)庫
        Page<Shop> page = query()
                .eq("type_id", typeId)  // 按店鋪類型篩選
                .page(new Page<>(current, SystemConstants.DEFAULT_PAGE_SIZE));  // 分頁查詢
        // 返回查詢結(jié)果
        return Result.ok(page.getRecords());
    }
    // 2. 需要地理查詢時,計算分頁參數(shù)
    int from = (current - 1) * SystemConstants.DEFAULT_PAGE_SIZE;  // 起始偏移量
    int end = current * SystemConstants.DEFAULT_PAGE_SIZE;          // 結(jié)束位置
    // 3. 從Redis中查詢附近店鋪ID(GEO查詢)
    String key = "shop:geo:" + typeId;  // GEO數(shù)據(jù)存儲的key
    // 執(zhí)行GEO搜索:以(x,y)為中心,5000米半徑范圍內(nèi),查詢end數(shù)量的店鋪
    GeoResults<RedisGeoCommands.GeoLocation<String>> results = stringRedisTemplate.opsForGeo().search(
            key,
            GeoReference.fromCoordinate(x, y),  // 中心點坐標(biāo)
            new Distance(5000),                // 搜索半徑(5公里)
            RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs()
                    .includeDistance()         // 包含距離信息
                    .limit(end)                // 限制返回數(shù)量
    );
    // 4. 處理查詢結(jié)果并獲取店鋪詳情
    if (results == null) {
        return Result.ok(Collections.emptyList());  // 無結(jié)果時返回空列表
    }
    List<GeoResult<RedisGeoCommands.GeoLocation<String>>> list = results.getContent();
    if (list.size() <= from) {
        return Result.ok(Collections.emptyList());  // 結(jié)果不足時分頁返回空
    }
    // 收集店鋪ID和距離信息
    List<Long> ids = new ArrayList<>(list.size());
    Map<String, Distance> distanceMap = new HashMap<>(list.size());
    // 跳過前from條記錄(分頁處理),然后處理剩余記錄
    list.stream().skip(from).forEach(result -> {
        String id = result.getContent().getName();  // 獲取店鋪ID
        ids.add(Long.valueOf(id));
        distanceMap.put(id, result.getDistance()); // 存儲店鋪距離
    });
    // 根據(jù)ID批量查詢店鋪詳情(保持ID順序)
    String strIds = StrUtil.join(",", ids);
    List<Shop> shops = query()
            .in("id", ids)  // 按ID列表查詢
            .last("ORDER BY FIELD(id," + strIds + ")")  // 保持Redis返回的順序
            .list();
    // 為每個店鋪設(shè)置距離信息
    for (Shop shop : shops) {
        shop.setDistance(distanceMap.get(shop.getId().toString()).getValue());
    }
    // 5. 返回帶距離信息的店鋪列表
    return Result.ok(shops);
}

4.Redis GEO search 方法的參數(shù)

排序方式

.sortAscending()    // 按距離升序排序(從近到遠(yuǎn))
.sortDescending()  // 按距離降序排序(從遠(yuǎn)到近)

返回內(nèi)容控制

.includeDistance()  // 在結(jié)果中包含距離信息
.includeCoordinates() // 在結(jié)果中包含坐標(biāo)信息
.includeName()     // 在結(jié)果中包含成員名稱(默認(rèn)包含)

結(jié)果限制

.limit(50)         // 限制返回結(jié)果數(shù)量(可用于簡單分頁)

單位設(shè)置

.includeDistance().withDistance(Metrics.KILOMETERS) // 指定距離單位
//支持的單位:
//Metrics.KILOMETERS(千米)
//Metrics.MILES(英里)
//Metrics.FEET(英尺)
//Metrics.METERS(米)

GeoReference 的三種主要形式

//1.fromCoordinate(x, y)
//作用:通過經(jīng)緯度坐標(biāo)指定中心點
//示例:
GeoReference.fromCoordinate(116.404, 39.915)  // 北京天安門坐標(biāo)
//2.fromMember(memberName)
//作用:通過 Redis中已存儲的GEO成員名稱指定中心點
//示例:
GeoReference.fromMember("北京站")  // 以已存儲的"北京站"坐標(biāo)為中心
//3.fromString("x,y")
//作用:通過字符串格式的坐標(biāo)指定中心點
//示例:
GeoReference.fromString("116.404,39.915")

如下為完整示例:

GeoResults<RedisGeoCommands.GeoLocation<String>> results = stringRedisTemplate.opsForGeo().search(
    "shop:geo:1",
    GeoReference.fromCoordinate(116.397904, 39.909005),
    new Distance(5, Metrics.KILOMETERS),
    RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs()
        .includeDistance()      // 包含距離
        .includeCoordinates()   // 包含坐標(biāo)
        .sortAscending()        // 按距離升序
        .limit(100)             // 最多返回100條
        .withDistance(Metrics.KILOMETERS) // 距離單位為千米
);

對于 Redis 6.2 及以上版本,還可以使用:

矩形范圍搜索

.byBox(width, height, Metrics.KILOMETERS) // 矩形范圍搜索

存儲搜索結(jié)果

.store("result-key")  // 將結(jié)果存儲到指定key
.storeDist("result-key") // 存儲帶距離的結(jié)果

到此這篇關(guān)于基于Redis實現(xiàn)-附近商鋪查詢的文章就介紹到這了,更多相關(guān)Redis附近商鋪查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解如何使用Redis作為高效緩存

    詳解如何使用Redis作為高效緩存

    Redis是一個高性能的 內(nèi)存存儲系統(tǒng),通常被用作 緩存 來加速數(shù)據(jù)訪問,提高應(yīng)用的吞吐量和響應(yīng)速度,本文詳細(xì)講解如何使用 Redis 作為高效緩存,包括基本原理、常見模式、最佳實踐以及優(yōu)化技巧,需要的朋友可以參考下
    2025-01-01
  • redis的key出現(xiàn)的\xac\xed\x00\x05t\x00亂碼問題及解決

    redis的key出現(xiàn)的\xac\xed\x00\x05t\x00亂碼問題及解決

    這篇文章主要介紹了redis的key出現(xiàn)的\xac\xed\x00\x05t\x00亂碼問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 如何使用注解方式實現(xiàn)?Redis?分布式鎖

    如何使用注解方式實現(xiàn)?Redis?分布式鎖

    這篇文章主要介紹了如何使用注解方式實現(xiàn)Redis分布式鎖,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,教大家如何優(yōu)雅的使用Redis分布式鎖,感興趣的小伙伴可以參考一下
    2022-07-07
  • Redis實現(xiàn)客戶端緩存的4種方式

    Redis實現(xiàn)客戶端緩存的4種方式

    客戶端緩存是指在應(yīng)用程序內(nèi)存中維護(hù)一份Redis數(shù)據(jù)的本地副本,以減少網(wǎng)絡(luò)請求次數(shù),降低延遲,并減輕Redis服務(wù)器負(fù)擔(dān),本文將分享Redis客戶端緩存的四種實現(xiàn)方式,大家可以參考一下
    2025-05-05
  • Redis上實現(xiàn)分布式鎖以提高性能的方案研究

    Redis上實現(xiàn)分布式鎖以提高性能的方案研究

    這篇文章主要介紹了Redis上實現(xiàn)分布式鎖以提高性能的方案研究,其中重點需要理解異步算法與鎖的自動釋放,需要的朋友可以參考下
    2015-12-12
  • Redis的Bitmap(位圖)詳解和命令演示

    Redis的Bitmap(位圖)詳解和命令演示

    Redis的位圖是由多個二進(jìn)制位組成的數(shù)組,數(shù)組中的每個二進(jìn)制位都有與之對應(yīng)的偏移量,用戶通過這些偏移量可以對位圖中指定的一個或多個二進(jìn)制位進(jìn)行操作,這篇文章主要給大家介紹了關(guān)于Redis的Bitmap(位圖)詳解和命令演示的相關(guān)資料,需要的朋友可以參考下
    2024-08-08
  • Redis使用布隆過濾器解決緩存雪崩的問題

    Redis使用布隆過濾器解決緩存雪崩的問題

    布隆過濾器可以幫助我們解決Redis緩存雪崩的問題,那什么是布隆過濾器、布隆過濾器又是如何使用如何解決緩存雪崩的問題的,讓我們帶著這一系列的問題去詳細(xì)了解布隆過濾器,感興趣的小伙伴跟著小編一起來看看吧
    2024-02-02
  • 一文快速搞懂Redis的幾種數(shù)據(jù)類型方式

    一文快速搞懂Redis的幾種數(shù)據(jù)類型方式

    這篇文章主要介紹了一文快速搞懂Redis的幾種數(shù)據(jù)類型方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Redis中如何設(shè)置日志

    Redis中如何設(shè)置日志

    這篇文章主要介紹了Redis中如何設(shè)置日志問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Redis中三種特殊數(shù)據(jù)類型命令詳解

    Redis中三種特殊數(shù)據(jù)類型命令詳解

    Geospatial是地理位置類型,我們可以用來查詢附近的人、計算兩人之間的距離等,這篇文章主要介紹了Redis中三種特殊數(shù)據(jù)類型命令詳解,需要的朋友可以參考下
    2024-05-05

最新評論