通过Redis拓展的GEO数据类型查询两地之间的距离
最近了解到redis还有几种拓展数据类型,GEO,hyperLogLog,bitmaps
GEO
GEOADD locations 116.419217 39.921133 beijin
GEOPOS locations beijin
GEODIST locations tianjin beijin km 计算距离
GEORADIUSBYMEMBER locations beijin 150 km 通过距离计算城市
注意:没有删除命令 它的本质是zset (type locations)
所以可以使用zrem key member 删除元素
zrange key 0 -1 表示所有 返回指定集合中所有value
hyperLogLog
Redis 在 2.8.9 版本添加了 HyperLogLog 结构。
Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的
在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
PFADD 2017_03_06:taibai 'yes' 'yes' 'yes' 'yes' 'no'
PFCOUNT 2017_03_06:taibai 统计有多少不同的值
1.PFADD 2017_09_08:taibai uuid9 uuid10 uu11
2.PFMERGE 2016_03_06:taibai 2017_09_08:taibai 合并
注意:本质还是字符串 ,有容错率,官方数据是0.81%
bitmaps
setbit taibai 500000 0
getbit taibai 500000
bitcount taibai
Bitmap本质是string,是一串连续的2进制数字(0或1),每一位所在的位置为偏移(offset)。
string(Bitmap)最大长度是512 MB,所以它们可以表示2 ^ 32=4294967296个不同的位。
代码部分
1.pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
2.application.yml
spring:
redis:
host: localhost
port: 6379
3.测试代码
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.Resource;
@SpringBootTest
class SpringbootDemoApplicationTests {
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Test
void testGetDistance() {
GeoOperations<String, Object> geoOperations = redisTemplate.opsForGeo();
//首先存入客户端上传的经纬度和指定地点的经纬度
// 将这些地址数据保存到redis中
geoOperations.add("GET_DISTANCE", new Point(116.40, 39.90), "beijing");
geoOperations.add("GET_DISTANCE", new Point(117.20, 39.12), "tianjin");
// 调用方法,计算天津与北京之间的距离;单位为KM
Distance distance = geoOperations.distance("GET_DISTANCE", "tianjin", "beijing", RedisGeoCommands.DistanceUnit.KILOMETERS);
double value = distance == null ? 0 : distance.getValue();
System.out.println(value);
}
}