当前位置: 首页 > news >正文

甘肃建设住房厅网站扁平 网站模板

甘肃建设住房厅网站,扁平 网站模板,安阳做网站推广,网站开发毕业设计中期汇报表抽奖 一堆用户参与进来#xff0c;然后随机抽取几个幸运用户给予实物/虚拟的奖品#xff1b;此时#xff0c;开发人员就需要写上一个抽奖的算法#xff0c;来实现幸运用户的抽取#xff1b;其实我们完全可以利用Redis的集合#xff08;Set#xff09;#xff0c;就能轻… 抽奖 一堆用户参与进来然后随机抽取几个幸运用户给予实物/虚拟的奖品此时开发人员就需要写上一个抽奖的算法来实现幸运用户的抽取其实我们完全可以利用Redis的集合Set就能轻松实现抽奖的功能 功能实现需要的API SADD key member1 [member2]添加一个或者多个参与用户SRANDMEMBER KEY [count]随机返回一个或者多个用户SPOP key随机返回一个或者多个用户并删除返回的用户 SRANDMEMBER 和 SPOP 主要用于两种不同的抽奖模式SRANDMEMBER 适用于一个用户可中奖多次的场景就是中奖之后不从用户池中移除继续参与其他奖项的抽取而 SPOP 就适用于仅能中一次的场景一旦中奖就将用户从用户池中移除后续的抽奖就不可能再抽到该用户 通常 SPOP 会用的会比较多。 Redis-Cli操作 127.0.0.1:6379 SADD raffle user1 (integer) 1 127.0.0.1:6379 SADD raffle user2 user3 user4 user5 user6 user7 user8 user9 user10 (integer) 9 127.0.0.1:6379 SRANDMEMBER raffle 2 1) user5 2) user2 127.0.0.1:6379 SPOP raffle 2 1) user3 2) user4 127.0.0.1:6379 SPOP raffle 2 1) user10 2) user9 代码实现 Slf4j SpringBootTest public class RaffleMain {private final String KEY_RAFFLE_PROFIX raffle:;AutowiredRedisTemplate redisTemplate;Testvoid test() {Integer raffleId 1;join(raffleId, 1000, 1001, 2233, 7890, 44556, 74512);List lucky lucky(raffleId, 2);log.info(活动{} 的幸运中奖用户是{}, raffleId, lucky);}public void join(Integer raffleId, Integer... userIds) {String key KEY_RAFFLE_PROFIX raffleId;redisTemplate.opsForSet().add(key, userIds);}public List lucky(Integer raffleId, long num) {String key KEY_RAFFLE_PROFIX raffleId;// 随机抽取 抽完之后将用户移除奖池List list redisTemplate.opsForSet().pop(key, num);// 随机抽取 抽完之后用户保留在池子里//List list redisTemplate.opsForSet().randomMembers(key, num);return list;}} 点赞收藏 有互动属性活动一般都会有点赞/收藏/喜欢等功能来提升用户之间的互动。 传统的实现用户点赞之后在数据库中记录一条数据同时一般都会在主题库中记录一个点赞/收藏汇总数来方便显示 Redis方案基于Redis的集合Set记录每个帖子/文章对应的收藏、点赞的用户数据同时set还提供了检查集合中是否存在指定用户用户快速判断用户是否已经点赞过 功能实现需要的API SADD key member1 [member2]添加一个或者多个成员点赞SCARD key获取所有成员的数量点赞数量SISMEMBER key member判断成员是否存在是否点赞SREM key member1 [member2] 移除一个或者多个成员点赞数量 Redis-Cli操作 127.0.0.1:6379 sadd like:article:1 user1 (integer) 1 127.0.0.1:6379 sadd like:article:1 user2 (integer) 1 # 获取成员数量点赞数量 127.0.0.1:6379 SCARD like:article:1 (integer) 2 # 判断成员是否存在是否点赞 127.0.0.1:6379 SISMEMBER like:article:1 user1 (integer) 1 127.0.0.1:6379 SISMEMBER like:article:1 user3 (integer) 0 # 移除一个或者多个成员取消点赞 127.0.0.1:6379 SREM like:article:1 user1 (integer) 1 127.0.0.1:6379 SCARD like:article:1 (integer) 1 代码实现 Slf4j SpringBootTest public class LikeMain {private final String KEY_LIKE_ARTICLE_PROFIX like:article:;AutowiredRedisTemplate redisTemplate;Testvoid test() {long articleId 100;Long likeNum like(articleId, 1001, 1002, 2001, 3005, 4003);unLike(articleId, 2001);likeNum likeNum(articleId);boolean b2001 isLike(articleId, 2001);boolean b3005 isLike(articleId, 3005);log.info(文章{} 点赞数量{} 用户2001的点赞状态{} 用户3005的点赞状态{}, articleId, likeNum, b2001, b3005);}/*** 点赞** param articleId 文章ID* return 点赞数量*/public Long like(Long articleId, Integer... userIds) {String key KEY_LIKE_ARTICLE_PROFIX articleId;Long add redisTemplate.opsForSet().add(key, userIds);return add;}public Long unLike(Long articleId, Integer... userIds) {String key KEY_LIKE_ARTICLE_PROFIX articleId;Long remove redisTemplate.opsForSet().remove(key, userIds);return remove;}public Long likeNum(Long articleId) {String key KEY_LIKE_ARTICLE_PROFIX articleId;Long size redisTemplate.opsForSet().size(key);return size;}public Boolean isLike(Long articleId, Integer userId) {String key KEY_LIKE_ARTICLE_PROFIX articleId;return redisTemplate.opsForSet().isMember(key, userId);}} 排行榜 排名、排行榜、热搜榜是很多活动、游戏都有的功能常用于用户活动推广、竞技排名、热门信息展示等功能 比如上面的热搜榜热度数据来源于全网用户的贡献但用户只关心热度最高的前50条。 常规的做法就是将用户的名次、分数等用于排名的数据更新到数据库然后查询的时候通过Order by limit 取出前50名显示如果是参与用户不多更新不频繁的数据采用数据库的方式也没有啥问题但是一旦出现爆炸性热点资讯比如大陆收复湾湾xxx某些绿了等等短时间会出现爆炸式的流量瞬间的压力可能让数据库扛不住 Redis方案将热点资讯全页缓存采用Redis的有序队列Sorted Set来缓存热度SCORES即可瞬间缓解数据库的压力同时轻松筛选出热度最高的50条 功能实现需要的命令 ZADD key score1 member1 [score2 member2]添加并设置SCORES支持一次性添加多个ZREVRANGE key start stop [WITHSCORES] 根据SCORES降序排列ZRANGE key start stop [WITHSCORES] 根据SCORES降序排列 Redis-Cli操作 # 单个插入 127.0.0.1:6379 ZADD ranking 1 user1 (integer) 1 # 批量插入 127.0.0.1:6379 ZADD ranking 10 user2 50 user3 3 user4 25 user5 (integer) 4 # 降序排列 不带SCORES 127.0.0.1:6379 ZREVRANGE ranking 0 -1 1) user3 2) user5 3) user2 4) user4 5) user1 # 降序排列 带SCORES 127.0.0.1:6379 ZREVRANGE ranking 0 -1 WITHSCORES 1) user3 2) 50 3) user5 4) 25 5) user2 6) 10 7) user4 8) 3 9) user1 10) 1 # 升序 127.0.0.1:6379 ZRANGE ranking 0 -1 WITHSCORES 1) user1 2) 1 3) user4 4) 3 5) user2 6) 10 7) user5 8) 25 9) user3 10) 50 代码实现 SpringBootTest Slf4j public class RankingTest {private final String KEY_RANKING ranking;AutowiredRedisTemplate redisTemplate;Testvoid test() {add(1001, (double) 60);add(1002, (double) 80);add(1003, (double) 100);add(1004, (double) 90);add(1005, (double) 70);// 取所有SetDefaultTypedTuple range range(0, -1);log.info(所有用户排序{}, range);// 前三名range range(0, 2);log.info(前三名排序{}, range);}public Boolean add(Integer userId, Double score) {Boolean add redisTemplate.opsForZSet().add(KEY_RANKING, userId, score);return add;}public SetDefaultTypedTuple range(long min, long max) {// 降序SetDefaultTypedTuple set redisTemplate.opsForZSet().reverseRangeWithScores(KEY_RANKING, min, max);// 升序//SetDefaultTypedTuple set redisTemplate.opsForZSet().rangeWithScores(KEY_RANKING, min, max);return set;} } 用户签到BitMap 很多活动为了拉动用户活跃度会加入比如连续签到的功能 传统做法用户每次签到时往是数据库插入一条签到数据展示的时候把本月或者指定周期的签到数据获取出来用于判断用户是否签到、以及连续签到情况此方式简单理解容易 Redis做法由于签到数据的关注点就2个是否签到0/1、连续性因此就完全可以利用BitMap位图来实现 如上图所示将一个月的31天用31个位4个字节来表示偏移量offset代表当前是第几天0/1表示当前是否签到连续签到只需从右往左校验连续为1的位数 由于String类型的最大上限是512M转换为bit则是2^32个bit位。 所需命令 SETBIT key offset value向指定位置offset存入一个0或1GETBIT key offset获取指定位置offset的bit值BITCOUNT key [start] [end]统计BitMap中值为1的bit位的数量BITFIELD: 操作查询修改自增BitMap中bit 数组中的指定位置offset的值这里最不容易理解的就是BITFIELD详情可参考https://deepinout.com/redis-cmd/redis-bitmap-cmd/redis-cmd-bitfield.html 而且这部分还必须理解了否则该需求的核心部分就没办法理解了 需求假如当前为8月4号检测本月的签到情况用户分别于1、3、4号签到过 Redis-Cli操作 # 8月1号的签到 127.0.0.1:6379 SETBIT RangeId:Sign:1:8899 0 1 (integer) 1# 8月3号的签到 127.0.0.1:6379 SETBIT RangeId:Sign:1:8899 2 1 (integer) 1# 8月4号的签到 127.0.0.1:6379 SETBIT RangeId:Sign:1:8899 3 1 (integer) 1# 查询各天的签到情况 # 查询1号 127.0.0.1:6379 GETBIT RangeId:Sign:1:8899 0 (integer) 1 # 查询2号 127.0.0.1:6379 GETBIT RangeId:Sign:1:8899 1 (integer) 0 # 查询3号 127.0.0.1:6379 GETBIT RangeId:Sign:1:8899 2 (integer) 1 # 查询4号 127.0.0.1:6379 GETBIT RangeId:Sign:1:8899 3 (integer) 1# 查询指定区间的签到情况 127.0.0.1:6379 BITFIELD RangeId:Sign:1:8899 get u4 0 1) (integer) 11 1-4号的签到情况为1011二进制 11十进制 代码实现-按月签到 Slf4j Service public class SignByMonthServiceImpl {AutowiredStringRedisTemplate stringRedisTemplate;private int dayOfMonth() {DateTime dateTime new DateTime();return dateTime.dayOfMonth().get();}/*** 按照月份和用户ID生成用户签到标识 UserId:Sign:560:2021-08** param userId 用户id* return*/private String signKeyWitMouth(String userId) {DateTime dateTime new DateTime();DateTimeFormatter fmt DateTimeFormat.forPattern(yyyy-MM);StringBuilder builder new StringBuilder(UserId:Sign:);builder.append(userId).append(:).append(dateTime.toString(fmt));return builder.toString();}/*** 设置标记位* 标记是否签到** param key* param offset* param tag* return*/public Boolean sign(String key, long offset, boolean tag) {return this.stringRedisTemplate.opsForValue().setBit(key, offset, tag);}/*** 统计计数** param key 用户标识* return*/public long bitCount(String key) {return stringRedisTemplate.execute((RedisCallbackLong) redisConnection - redisConnection.bitCount(key.getBytes()));}/*** 获取多字节位域*/public ListLong bitfield(String buildSignKey, int limit, long offset) {return this.stringRedisTemplate.opsForValue().bitField(buildSignKey, BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(limit)).valueAt(offset));}/*** 判断是否被标记** param key* param offest* return*/public Boolean container(String key, long offest) {return this.stringRedisTemplate.opsForValue().getBit(key, offest);}/*** 用户今天是否签到** param userId* return*/public int checkSign(String userId) {DateTime dateTime new DateTime();String signKey this.signKeyWitMouth(userId);int offset dateTime.getDayOfMonth() - 1;int value this.container(signKey, offset) ? 1 : 0;return value;}/*** 查询用户当月签到日历** param userId* return*/public MapString, Boolean querySignedInMonth(String userId) {DateTime dateTime new DateTime();int lengthOfMonth dateTime.dayOfMonth().getMaximumValue();MapString, Boolean signedInMap new HashMap(dateTime.getDayOfMonth());String signKey this.signKeyWitMouth(userId);ListLong bitfield this.bitfield(signKey, lengthOfMonth, 0);if (!CollectionUtils.isEmpty(bitfield)) {long signFlag bitfield.get(0) null ? 0 : bitfield.get(0);DateTimeFormatter fmt DateTimeFormat.forPattern(yyyy-MM-dd);for (int i lengthOfMonth; i 0; i--) {DateTime dateTime1 dateTime.withDayOfMonth(i);signedInMap.put(dateTime1.toString(fmt), signFlag 1 1 ! signFlag);signFlag 1;}}return signedInMap;}/*** 用户签到** param userId* return*/public boolean signWithUserId(String userId) {int dayOfMonth this.dayOfMonth();String signKey this.signKeyWitMouth(userId);long offset (long) dayOfMonth - 1;boolean re false;if (Boolean.TRUE.equals(this.sign(signKey, offset, Boolean.TRUE))) {re true;}// 查询用户连续签到次数,最大连续次数为7天long continuousSignCount this.queryContinuousSignCount(userId, 7);return re;}/*** 统计当前月份一共签到天数** param userId*/public long countSignedInDayOfMonth(String userId) {String signKey this.signKeyWitMouth(userId);return this.bitCount(signKey);}/*** 查询用户当月连续签到次数** param userId* return*/public long queryContinuousSignCountOfMonth(String userId) {int signCount 0;String signKey this.signKeyWitMouth(userId);int dayOfMonth this.dayOfMonth();ListLong bitfield this.bitfield(signKey, dayOfMonth, 0);if (!CollectionUtils.isEmpty(bitfield)) {long signFlag bitfield.get(0) null ? 0 : bitfield.get(0);DateTime dateTime new DateTime();// 连续不为0即为连续签到次数当天未签到情况下for (int i 0; i dateTime.getDayOfMonth(); i) {if (signFlag 1 1 signFlag) {if (i 0) break;} else {signCount 1;}signFlag 1;}}return signCount;}/*** 以7天一个周期连续签到次数** param period 周期* return*/public long queryContinuousSignCount(String userId, Integer period) {//查询目前连续签到次数long count this.queryContinuousSignCountOfMonth(userId);//按最大连续签到取余if (period ! null period count) {long num count % period;if (num 0) {count period;} else {count num;}}return count;} } 测试 SpringBootTest Slf4j public class SignTest2 {Autowiredprivate SignByMonthServiceImpl signByMonthService;Autowiredprivate StringRedisTemplate redisTemplate;/*** 测试用户按月签到*/Testpublic void querySignDay() {//模拟用户签到//for(int i5;i19;i){redisTemplate.opsForValue().setBit(UserId:Sign:560:2022-08, 0, true);//}System.out.println(560用户今日是否已签到: this.signByMonthService.checkSign(560));MapString, Boolean stringBooleanMap this.signByMonthService.querySignedInMonth(560);System.out.println(本月签到情况:);for (Map.EntryString, Boolean entry : stringBooleanMap.entrySet()) {System.out.println(entry.getKey() : (entry.getValue() ? √ : -));}long countSignedInDayOfMonth this.signByMonthService.countSignedInDayOfMonth(560);System.out.println(本月一共签到: countSignedInDayOfMonth 天);System.out.println(目前连续签到: this.signByMonthService.queryContinuousSignCount(560, 7) 天);} } 代码实现-指定时间签到 Slf4j Service public class SignByRangeServiceImpl {AutowiredStringRedisTemplate stringRedisTemplate;/*** 根据区间的id 以及用户id 拼接key** param rangeId 区间ID 一般是指定活动的ID等* param userId 用户的ID* return*/private String signKey(Integer rangeId, Integer userId) {StringBuilder builder new StringBuilder(RangeId:Sign:);builder.append(rangeId).append(:).append(userId);return builder.toString();}/*** 获取当前时间与起始时间的间隔天数** param start 起始时间* return*/private int intervalTime(LocalDateTime start) {return (int) (LocalDateTime.now().toLocalDate().toEpochDay() - start.toLocalDate().toEpochDay());}/*** 设置标记位* 标记是否签到** param key 签到的key* param offset 偏移量 一般是指当前时间离起始时间活动开始的天数* param tag 是否签到 true:签到 false:未签到* return*/private Boolean setBit(String key, long offset, boolean tag) {return this.stringRedisTemplate.opsForValue().setBit(key, offset, tag);}/*** 统计计数** param key 统计的key* return*/private long bitCount(String key) {return stringRedisTemplate.execute((RedisCallbackLong) redisConnection - redisConnection.bitCount(key.getBytes()));}/*** 获取多字节位域** param key 缓存的key* param limit 获取多少* param offset 偏移量是多少* return*/private ListLong bitfield(String key, int limit, long offset) {return this.stringRedisTemplate.opsForValue().bitField(key, BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(limit)).valueAt(offset));}/*** 判断是否签到** param key 缓存的key* param offest 偏移量 指当前时间距离起始时间的天数* return*/private Boolean container(String key, long offest) {return this.stringRedisTemplate.opsForValue().getBit(key, offest);}/*** 根据起始时间进行签到** param rangeId* param userId* param start* return*/public Boolean sign(Integer rangeId, Integer userId, LocalDateTime start) {int offset intervalTime(start);String key signKey(rangeId, userId);return setBit(key, offset, true);}/*** 根据偏移量签到** param rangeId* param userId* param offset* return*/public Boolean sign(Integer rangeId, Integer userId, long offset) {String key signKey(rangeId, userId);return setBit(key, offset, true);}/*** 用户今天是否签到** param userId* return*/public Boolean checkSign(Integer rangeId, Integer userId, LocalDateTime start) {long offset intervalTime(start);String key this.signKey(rangeId, userId);return this.container(key, offset);}/*** 统计当前月份一共签到天数** param userId*/public long countSigned(Integer rangeId, Integer userId) {String signKey this.signKey(rangeId, userId);return this.bitCount(signKey);}public MapString, Boolean querySigned(Integer rangeId, Integer userId, LocalDateTime start) {int days intervalTime(start);MapString, Boolean signedInMap new HashMap(days);String signKey this.signKey(rangeId, userId);ListLong bitfield this.bitfield(signKey, days 1, 0);if (!CollectionUtils.isEmpty(bitfield)) {long signFlag bitfield.get(0) null ? 0 : bitfield.get(0);DateTimeFormatter fmt DateTimeFormatter.ofPattern(yyyy-MM-dd);for (int i days; i 0; i--) {LocalDateTime localDateTime start.plusDays(i);signedInMap.put(localDateTime.format(fmt), signFlag 1 1 ! signFlag);signFlag 1;}}return signedInMap;}/*** 查询用户当月连续签到次数** param userId* return*/public long queryContinuousSignCount(Integer rangeId, Integer userId, LocalDateTime start) {int signCount 0;String signKey this.signKey(rangeId, userId);int days this.intervalTime(start);ListLong bitfield this.bitfield(signKey, days 1, 0);if (!CollectionUtils.isEmpty(bitfield)) {long signFlag bitfield.get(0) null ? 0 : bitfield.get(0);DateTime dateTime new DateTime();// 连续不为0即为连续签到次数当天未签到情况下for (int i 0; i dateTime.getDayOfMonth(); i) {if (signFlag 1 1 signFlag) {if (i 0) break;} else {signCount 1;}signFlag 1;}}return signCount;} } 测试 SpringBootTest Slf4j public class SignTest {AutowiredSignByRangeServiceImpl signByRangeService;Testvoid test() {DateTimeFormatter isoDateTime DateTimeFormatter.ISO_DATE_TIME;// 活动开始时间LocalDateTime start LocalDateTime.of(2022, 8, 1, 1, 0, 0);Integer rangeId 1;Integer userId 8899;log.info(签到开始时间: {}, start.format(isoDateTime));log.info(活动ID: {} 用户ID: {}, rangeId, userId);// 手动指定偏移量签到signByRangeService.sign(rangeId, userId, 0);// 判断是否签到Boolean signed signByRangeService.checkSign(rangeId, userId, start);log.info(今日是否签到: {}, signed ? √ : -);// 签到Boolean sign signByRangeService.sign(rangeId, userId, start);log.info(签到操作之前的签到状态{} -表示今日第一次签到√表示今天已经签到过了, sign ? √ : -);// 签到总数long countSigned signByRangeService.countSigned(rangeId, userId);log.info(总共签到: {} 天, countSigned);// 连续签到的次数long continuousSignCount signByRangeService.queryContinuousSignCount(rangeId, userId, start);log.info(连续签到: {} 天, continuousSignCount);// 签到的详情MapString, Boolean stringBooleanMap signByRangeService.querySigned(rangeId, userId, start);for (Map.EntryString, Boolean entry : stringBooleanMap.entrySet()) {log.info(签到详情 {} : {}, entry.getKey(), (entry.getValue() ? √ : -));}} } GEO搜附近 活动中经常有展示附近用户、商家的诉求 如果自己想要根据经纬度来实现一个搜索附近的功能是非常麻烦的但是Redis 在3.2的版本新增了Redis GEO用于存储地址位置信息并对支持范围搜索基于GEO就能轻松且快速的开发一个搜索附近的功能 GEO API 及Redis-cli 操作 geoadd新增位置坐标 127.0.0.1:6379 GEOADD drinks 116.62445 39.86206 starbucks 117.3514785 38.7501247 yidiandian 116.538542 39.75412 xicha (integer) 3 geopos获取位置坐标 127.0.0.1:6379 GEOPOS drinks starbucks 1) 1) 116.624451577663421632) 39.86206038535793539 127.0.0.1:6379 GEOPOS drinks starbucks yidiandian mxbc 1) 1) 116.624451577663421632) 39.86206038535793539 2) 1) 117.351480424404144292) 38.75012383773680114 3) (nil) geodist计算两个位置之间的距离 单位参数 m 米默认单位。km 千米。mi 英里。ft 英尺。 127.0.0.1:6379 GEODIST drinks starbucks yidiandian 138602.4133 127.0.0.1:6379 GEODIST drinks starbucks xicha 14072.1255 127.0.0.1:6379 GEODIST drinks starbucks xicha m 14072.1255 127.0.0.1:6379 GEODIST drinks starbucks xicha km 14.0721 georadius根据用户给定的经纬度坐标来获取指定范围内的地理位置集合 参数说明 m 米默认单位。km 千米。mi 英里。ft 英尺。WITHDIST: 在返回位置元素的同时 将位置元素与中心之间的距离也一并返回。WITHCOORD: 将位置元素的经度和纬度也一并返回。WITHHASH: 以 52 位有符号整数的形式 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试 实际中的作用并不大。COUNT 限定返回的记录数。ASC: 查找结果根据距离从近到远排序。DESC: 查找结果根据从远到近排序。 127.0.0.1:6379 GEORADIUS drinks 116 39 100 km WITHDIST 1) 1) xicha2) 95.8085 127.0.0.1:6379 GEORADIUS drinks 116 39 100 km WITHDIST WITHCOORD 1) 1) xicha2) 95.80853) 1) 116.538540422916412352) 39.75411928478748536 127.0.0.1:6379 GEORADIUS drinks 116 39 100 km WITHDIST WITHCOORD WITHHASH 1) 1) xicha2) 95.80853) (integer) 40691518008823014) 1) 116.538540422916412352) 39.75411928478748536127.0.0.1:6379 GEORADIUS drinks 116 39 120 km WITHDIST WITHCOORD COUNT 1 1) 1) xicha2) 95.80853) 1) 116.538540422916412352) 39.75411928478748536127.0.0.1:6379 GEORADIUS drinks 116 39 120 km WITHDIST WITHCOORD COUNT 1 ASC 1) 1) xicha2) 95.80853) 1) 116.538540422916412352) 39.75411928478748536127.0.0.1:6379 GEORADIUS drinks 116 39 120 km WITHDIST WITHCOORD COUNT 1 DESC 1) 1) starbucks2) 109.87033) 1) 116.624451577663421632) 39.86206038535793539 georadiusbymember根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。功能和上面的georadius类似只是georadius是以经纬度坐标为中心这个是以某个地点为中心 geohash返回一个或多个位置对象的 geohash 值。 127.0.0.1:6379 GEOHASH drinks starbucks xicha 1) wx4fvbem6d0 2) wx4f5vhb8b0 代码实现 SpringBootTest Slf4j public class GEOTest {private final String KEY geo:drinks;AutowiredRedisTemplate redisTemplate;Testpublic void test() {add(starbucks, new Point(116.62445, 39.86206));add(yidiandian, new Point(117.3514785, 38.7501247));add(xicha, new Point(116.538542, 39.75412));get(starbucks, yidiandian, xicha);GeoResults nearByXY getNearByXY(new Point(116, 39), new Distance(120, Metrics.KILOMETERS));ListGeoResult content nearByXY.getContent();for (GeoResult geoResult : content) {log.info({}, geoResult.getContent());}GeoResults nearByPlace getNearByPlace(starbucks, new Distance(120, Metrics.KILOMETERS));content nearByPlace.getContent();for (GeoResult geoResult : content) {log.info({}, geoResult.getContent());}getGeoHash(starbucks, yidiandian, xicha);del(yidiandian, xicha);}private void add(String name, Point point) {Long add redisTemplate.opsForGeo().add(KEY, point, name);log.info(成功添加名称{} 的坐标信息信息{}, name, point);}private void get(String... names) {ListPoint position redisTemplate.opsForGeo().position(KEY, names);log.info(获取名称为{} 的坐标信息{}, names, position);}private void del(String... names) {Long remove redisTemplate.opsForGeo().remove(KEY, names);log.info(删除名称为{} 的坐标信息数量{}, names, remove);}/*** 根据坐标 获取指定范围的位置** param point* param distance* return*/private GeoResults getNearByXY(Point point, Distance distance) {Circle circle new Circle(point, distance);RedisGeoCommands.GeoRadiusCommandArgs args RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance(). // 包含距离includeCoordinates(). // 包含坐标sortAscending(). // 排序 还可选sortDescending()limit(5); // 获取前多少个GeoResults geoResults redisTemplate.opsForGeo().radius(KEY, circle, args);log.info(根据坐标获取{} {} 范围的数据{}, point, distance, geoResults);return geoResults;}/*** 根据一个位置获取指定范围内的其他位置** param name* param distance* return*/private GeoResults getNearByPlace(String name, Distance distance) {RedisGeoCommands.GeoRadiusCommandArgs args RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance(). // 包含距离includeCoordinates(). // 包含坐标sortAscending(). // 排序 还可选sortDescending()limit(5); // 获取前多少个GeoResults geoResults redisTemplate.opsForGeo().radius(KEY, name, distance, args);log.info(根据位置{} 获取 {} 范围的数据{}, name, distance, geoResults);return geoResults;}/*** 获取GEO HASH** param names* return*/private ListString getGeoHash(String... names) {ListString hash redisTemplate.opsForGeo().hash(KEY, names);log.info(names{} 对应的hash{}, names, hash);return hash;} } 执行日志 成功添加名称starbucks 的坐标信息信息Point [x116.624450, y39.862060] 成功添加名称yidiandian 的坐标信息信息Point [x117.351479, y38.750125] 成功添加名称xicha 的坐标信息信息Point [x116.538542, y39.754120]获取名称为[starbucks, yidiandian, xicha] 的坐标信息[Point [x116.624452, y39.862060], Point [x117.351480, y38.750124], Point [x116.538540, y39.754119]]根据坐标获取Point [x116.000000, y39.000000] 120.0 KILOMETERS 范围的数据GeoResults: [averageDistance: 102.8394 KILOMETERS, results: GeoResult [content: RedisGeoCommands.GeoLocation(namexicha, pointPoint [x116.538540, y39.754119]), distance: 95.8085 KILOMETERS, ],GeoResult [content: RedisGeoCommands.GeoLocation(namestarbucks, pointPoint [x116.624452, y39.862060]), distance: 109.8703 KILOMETERS, ]] RedisGeoCommands.GeoLocation(namexicha, pointPoint [x116.538540, y39.754119]) RedisGeoCommands.GeoLocation(namestarbucks, pointPoint [x116.624452, y39.862060])根据位置starbucks 获取 120.0 KILOMETERS 范围的数据GeoResults: [averageDistance: 7.03605 KILOMETERS, results: GeoResult [content: RedisGeoCommands.GeoLocation(namestarbucks, pointPoint [x116.624452, y39.862060]), distance: 0.0 KILOMETERS, ],GeoResult [content: RedisGeoCommands.GeoLocation(namexicha, pointPoint [x116.538540, y39.754119]), distance: 14.0721 KILOMETERS, ]] RedisGeoCommands.GeoLocation(namestarbucks, pointPoint [x116.624452, y39.862060]) RedisGeoCommands.GeoLocation(namexicha, pointPoint [x116.538540, y39.754119])names[starbucks, yidiandian, xicha] 对应的hash[wx4fvbem6d0, wwgkqqhxzd0, wx4f5vhb8b0]删除名称为[yidiandian, xicha] 的坐标信息数量2
http://www.ho-use.cn/article/10818338.html

相关文章:

  • 淮南市住房与城乡建设部网站做徽标哪个网站素材多
  • 创意设计网站推荐深圳市工程建设造价网站
  • 网站做中英版营销策划好的网站
  • 保定网页设计招聘网站查询网站备案时间
  • 无锡企业网站设计网站运行速度慢的原因
  • 做加工都在哪个网站推广wordpress个人中心
  • 飞扬动力网站建设dedecms 旅游网站模板下载
  • 网站建设项目延期验收申请ido手表官网
  • 官方网站建设的重要性广东省备案网站建设方案书
  • 阿里云一键建站网站在线购物网站模板
  • 凡科建站是不是关闭企业网站自贡市建设局网站
  • 企业网站管理的含义及内容二级域名网站建设规范
  • 做预定网站的作用个人博客网站页面
  • 校园网站做自己的广告企业标准
  • 河南天元建设公司网站使网站有流量
  • 网站的标题优化怎么做烟台企业做网站
  • 请问哪个网站可以做当地向导孝感市建设网站
  • 企业静态网站需要备案吗wordpress体验
  • 丽江网站建设 莱芜html 公司网站 代码下载
  • 开封网站建设优化网站怎么做才能被百度抓取到
  • 温州市网站建设wordpress插件+手机版
  • 做网站规划wordpress精美博客主题
  • wordpress 手机lianxu播放seo引擎优化是什么
  • 泰州营销型网站万能图片编辑器
  • 建立网站的主要流程有哪些步骤wordpress百度地图插件下载失败
  • 深圳做微信商城网站建设暴雪倒闭
  • 深网站建设网站推广方法主要有
  • 学院门户网站建设自评影响网站pr的主要因素有哪些
  • 百度推广自己做网站吗网站建设要做哪些工作室
  • dede网站如何做中英文版本wordpress 一键置顶