目錄
一、GEO
1、概念
2、相關(guān)命令
1.GEOADD
2.GEODIST
3.GEOHASH
4.GEOPOS
5.GEORADIUS
6.GEOSEARCH
7.GEOSEARCHSTORE
二、附近的店鋪
1、實(shí)現(xiàn)思路
2、代碼實(shí)現(xiàn)
一、GEO
1、概念
GEO全稱Geolocation,Redis種的一種數(shù)據(jù)結(jié)構(gòu)他代表地理坐標(biāo)
2、相關(guān)命令
1.GEOADD
向redis中添加一個(gè)地理空間信息,其中包含經(jīng)度、維度、值(member)
2.GEODIST
計(jì)算兩個(gè)指定點(diǎn)之間的距離并返回
3.GEOHASH
將指定member的坐標(biāo)轉(zhuǎn)為hash字符串形式并返回
4.GEOPOS
返回指定member的左邊
5.GEORADIUS
指定圓心、半徑、找到該圓內(nèi)包含的所有member,并按照與圓心之間的距離排序后返回。6.2以后已經(jīng)廢棄
6.GEOSEARCH
在指定的范圍內(nèi)搜索member,并按照與指定點(diǎn)之間的距離進(jìn)行排序后返回,這個(gè)范圍可以是矩形也可以是圓形
7.GEOSEARCHSTORE
與第六個(gè)相同,不過該命令可以將結(jié)果存儲(chǔ)到一個(gè)指定的key中文章來源:http://www.zghlxwxcb.cn/news/detail-468068.html
二、附近的店鋪
1、實(shí)現(xiàn)思路
在數(shù)據(jù)庫(kù)層面,我們?cè)诘赇伇砩暇S護(hù)兩個(gè)字段分別是x、y對(duì)應(yīng)經(jīng)緯度,然后將這些店鋪的類型id作為geo數(shù)據(jù)類型的key將該類型對(duì)應(yīng)的店鋪id作為member以及經(jīng)緯度xy存入member對(duì)應(yīng)的經(jīng)緯度中,首先我們需要將查出來的店鋪信息通過代碼(推薦使用Stream流)將相同類型店鋪存的id作為key在同一個(gè)的map中,然后遍歷該集合以類型id作為redis的key的組成,將店鋪id與經(jīng)緯度存入geo中,此時(shí)當(dāng)客戶端傳來要查詢的店鋪類型與用戶自身的地理位置時(shí),我們只需要通過上述geo數(shù)據(jù)結(jié)構(gòu)來處理按照距離由近到遠(yuǎn)的返回店鋪id結(jié)合,然后查詢數(shù)據(jù)庫(kù)將該id對(duì)應(yīng)的店鋪信息查出后設(shè)置他們各自的距離后返回給前端文章來源地址http://www.zghlxwxcb.cn/news/detail-468068.html
2、代碼實(shí)現(xiàn)
List<Shop> test(Integer typeId, Integer page, Integer size, Double x, Double y) {
// 參數(shù)中 typeId為類型id page當(dāng)前頁(yè)數(shù) size每頁(yè)數(shù)據(jù)量 x經(jīng)度 y維度
// 首先判斷是否需要根據(jù)坐標(biāo)查詢:判斷客戶端是否傳回用戶的地理位置
if (x == null || y == null) {
// 不需要按照地理位置查詢,則進(jìn)行正常分頁(yè)查詢
// TODO:調(diào)用mapper層查詢數(shù)據(jù)庫(kù)
return null;
}
// 2.計(jì)算分頁(yè)參數(shù)
int from = (page - 1) * size;
int end = page * size;
// 3.查詢r(jià)edis 根據(jù)距離排序
String key = "shop:geo:" + typeId;
GeoResults<RedisGeoCommands.GeoLocation<String>> search = stringRedisTemplate.opsForGeo()
.search(
key, // key
GeoReference.fromCoordinate(new Point(x, y)), // 中心點(diǎn)的經(jīng)緯度
new Distance(5000), // 查詢范圍單位默認(rèn)是m
RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs().includeDistance().limit(end) // 將距離返回查詢到end
);
if (search == null) return null;
// 4.截取需要的數(shù)據(jù)
List<GeoResult<RedisGeoCommands.GeoLocation<String>>> content = search.getContent();
if (content.size() < from) {
// 沒有下一頁(yè)了
return null;
}
List<Long> ids = new ArrayList<>(content.size()); // 存儲(chǔ)用戶id
Map<String,Distance> distanceMap = new HashMap<>(content.size()); // 存儲(chǔ)距離
// 截取相應(yīng)的部分
content.stream().skip(from).forEach(re -> {
// 獲取id
String shopIdStr = re.getContent().getName();
ids.add(Long.valueOf(shopIdStr));
// 獲取距離
Distance distance = re.getDistance();
distanceMap.put(shopIdStr,distance);
});
// 根據(jù)id去查詢對(duì)應(yīng)的店鋪
List<Shop> dbShops = shopMapper.queryById(ids);
// 將對(duì)應(yīng)的距離賦值給每個(gè)shop對(duì)象后返回
for (Shop shop:dbShops) {
shop.setDistance(distanceMap.get(shop.getId().toString()).getValue());
}
return dbShops;
}
到了這里,關(guān)于【Redis】GEO數(shù)據(jù)類型之附近的店鋪實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!