最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于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的簡寫形式,代表地理坐標。Redis在3.2版本中加入到了對GEO的支持,允許存儲地理坐標信息,幫助我們根據(jù)經(jīng)緯度來檢索數(shù)據(jù),常見命令如下:

  • GEOADD: 添加一個地理空間信息,包含:經(jīng)度(longitude)、緯度(latitude)、值(member)
  • GEODIST: 計算指定的兩個點之間的距離并返回
  • GEOHASH: 將指定member的坐標轉(zhuǎn)為hash字符串形式并返回
  • GEOPOS: 返回指定member的坐標
  • 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) {
        // 不需要地理坐標查詢時,直接按類型分頁查詢數(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),  // 中心點坐標
            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()    // 按距離升序排序(從近到遠)
.sortDescending()  // 按距離降序排序(從遠到近)

返回內(nèi)容控制

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

結(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)緯度坐標指定中心點
//示例:
GeoReference.fromCoordinate(116.404, 39.915)  // 北京天安門坐標
//2.fromMember(memberName)
//作用:通過 Redis中已存儲的GEO成員名稱指定中心點
//示例:
GeoReference.fromMember("北京站")  // 以已存儲的"北京站"坐標為中心
//3.fromString("x,y")
//作用:通過字符串格式的坐標指定中心點
//示例:
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()   // 包含坐標
        .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消息隊列實現(xiàn)秒殺教程

    Redis消息隊列實現(xiàn)秒殺教程

    這篇文章主要介紹了Redis消息隊列實現(xiàn)秒殺教程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • 詳解如何使用Redis作為高效緩存

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

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

    淺析Redis Sentinel 與 Redis Cluster

    本文主要介紹Redis Sentinel 及 Redis Cluster的區(qū)別及用法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06
  • 推薦幾款 Redis 可視化工具(太厲害了)

    推薦幾款 Redis 可視化工具(太厲害了)

    這篇文章主要介紹了推薦幾款 Redis 可視化工具,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-04-04
  • 華為歐拉openEuler編譯安裝Redis的實現(xiàn)步驟

    華為歐拉openEuler編譯安裝Redis的實現(xiàn)步驟

    本文主要介紹了華為歐拉openEuler編譯安裝Redis的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • 詳解Redis 數(shù)據(jù)類型

    詳解Redis 數(shù)據(jù)類型

    這篇文章主要介紹了Redis 數(shù)據(jù)類型的相關(guān)資料,文中講解非常細致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-08-08
  • Redis中3種特殊的數(shù)據(jù)類型(BitMap、Geo和HyperLogLog)

    Redis中3種特殊的數(shù)據(jù)類型(BitMap、Geo和HyperLogLog)

    這篇文章主要給大家介紹了關(guān)于Redis中3種特殊的數(shù)據(jù)類型(BitMap、GEOADD和GEODIST)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • Redis中群集三種模式的實現(xiàn)

    Redis中群集三種模式的實現(xiàn)

    Redis群集有三種模式,分別是主從同步/復(fù)制、哨兵模式、Cluster,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-11-11
  • Redis在項目中常見的12種使用場景示例和說明

    Redis在項目中常見的12種使用場景示例和說明

    Redis是一個開源的高性能鍵值對數(shù)據(jù)庫,它以其內(nèi)存中數(shù)據(jù)存儲、鍵過期策略、持久化、事務(wù)、豐富的數(shù)據(jù)類型支持以及原子操作等特性,在許多項目中扮演著關(guān)鍵角色,以下是整理的12個Redis在項目中常見的使用場景舉例說明和解釋
    2024-06-06
  • Redis禁用命令、危險命令及規(guī)避方法

    Redis禁用命令、危險命令及規(guī)避方法

    這篇文章主要介紹了Redis禁用命令、危險命令及規(guī)避方法,本文介紹了個非常致命的兩個命令以及用配置文件禁用這些命令的方法,需要的朋友可以參考下
    2015-06-06

最新評論

页游| 闸北区| 龙门县| 顺平县| 无棣县| 分宜县| 犍为县| 陆河县| 宜川县| 泸水县| 屯留县| 岳池县| 石楼县| 资中县| 鲜城| 蒲江县| 柳林县| 九寨沟县| 深圳市| 麻栗坡县| 运城市| 云安县| 凉城县| 扬中市| 清徐县| 繁昌县| 攀枝花市| 湄潭县| 周宁县| 孙吴县| 江都市| 驻马店市| 安福县| 夹江县| 海伦市| 睢宁县| 刚察县| 海南省| 广昌县| 西充县| 密山市|