利用redis实现位置搜索功能(类似:微信附近的人,根据座标来实现,测试可行,没实际用到)
1. 利用redis的geo功能
主要功能有:
- geoadd key longitude latitude member … 添加成员经纬度
# 添加了 beijing、tianjin、shijiazhuang、tangshan 的座标到 locations 中 geoadd locations 116.0 39.6 beijing 117.1 39.1 tianjin 114.3 38.0 shijiazhuang 118.0 39.4 tangshan
- geopos key member1 member2 … 显示成员经纬度
# 显示成员经纬度 geopos locations member1 member2 # 结果: 1) 1) "116.28000229597091675" 2) "39.5500007245470826" 2) 1) "114.29000169038772583" 2) "38.01999994251037407"
- geodist key member1 member2 km 显示成员的距离(单位有:)
表示符号 单位 m 米 km 千米 mi 英里 ft 尺 geodist locations beijing shijiazhuang km # 结果: "242.3263"
- georadius key longitude latitude 100 km 找指定经纬度周围100km之内的点,后面还有参数:
参数 含义 withdist 距离也写出来 withcoord 座标也显示出来 withhash 座标的hash值也写出来 withradius 座标的经纬度也写出来 ASC、DESC 排序方式,按照距离的 升序、降序排列) COUNT 3 只显示前3条数据,可以修改该值 store aa 把结果存入aa,zset格式,以座标hash为score storedist bb 把结果存入bb,zset格式,以距离为score georadius locations 117 39 100 km withdist # 结果: 1) 1) "beijing" 2) "87.0941" 2) 1) "tianjin" 2) "13.6619" 3) 1) "tangshan" 2) "96.7842"
- georadiusbymember key member1 100 km 找key中的member1周围100km的点,后面的参数与georadius一样
georadiusbymember locations beijing 150 km withcoord # 结果: 1) 1) "beijing" 2) 1) "116.28000229597091675" 2) "39.5500007245470826" 2) 1) "tianjin" 2) 1) "117.12000042200088501" 2) "39.0800000535766543" 3) 1) "tangshan" 2) 1) "118.01000028848648071" 2) "39.37999951111137165"
- zrem key member2 删除key中的member2,geo也是利用有序列表zset来实现的,其以座标的hash值为member的score
2. 在django中使用该功能
- 需要用到 django_redis 模块
# 安装
pip install django-redis
# 使用
from django_redis import get_redis_connection
conn = get_redis_connection("default")
# 下面是django中对应上面的方法的使用方法,注释掉的部分是django中该方法的参数,与redis中的略有不同
conn.geoadd(...)
# def geoadd(self, name, *values):
conn.geopos(...)
# def geopos(self, name, *values):
conn.geohash(...)
# def geohash(self, name, *values):
conn.geodist(...)
# def geodist(self, name, place1, place2, unit=None):
conn.georadius(...)
# def georadius(self, name, longitude, latitude, radius, unit=None,
# withdist=False, withcoord=False, withhash=False, count=None,
# sort=None, store=None, store_dist=None):
conn.georadiusbymember(...)
# def georadius(self, name, place, radius, unit=None,
# withdist=False, withcoord=False, withhash=False,
# count=None, sort=None, store=None, store_dist=None):
conn.zrem(...)
# def zrem(self, name, *values):