前言
最近公司项目需要实现附近的门店功能,通过查询资料发现很多方法都可以实现。
包括Mysql,Redis,Mongodb,PostgreSQL等
其中分别选择了redis和mongodb进行实现。
一、附近门店功能
redis实现
redis4.0.14版本,使用redis自带的geo命令来实现功能。具体的命令详情可参考官方文档 https://redis.io/commands/geoadd
1、引入要使用的jar包,工程是springboot项目,直接maven引入redis依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
2、代码实现redis操作
包括了插入、删除数据,以及查询附近的数据
@Data
public class Geo<T> {
private T object;
private double distance;
}
@Component
public class RedisGeo<T> {
@Resource(name = "redisTemplateBusiness")
private RedisTemplate redisTemplate;
public void setGeo(String key, double longitude, double latitude, T object) {
redisTemplate.opsForGeo().add(key, new Point(longitude, latitude), object);
}
public void removeGeo(String key, T object) {
redisTemplate.opsForGeo().remove(key, object);
}
public List<Geo<T>> getNearbyByGeo(String key, double longitude, double latitude, int distance, int limit) {
List<Geo<T>> geos = new ArrayList<>();
BoundGeoOperations boundGeoOperations = redisTemplate.boundGeoOps(key);
Point point = new Point(longitude, latitude);
Circle within = new Circle(point, distance);
RedisGeoCommands.GeoRadiusCommandArgs geoRadiusArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
geoRadiusArgs = geoRadiusArgs.includeDistance();
geoRadiusArgs.limit(limit);
geoRadiusArgs.sortAscending();
GeoResults<RedisGeoCommands.GeoLocation<Object>> geoResults = boundGeoOperations.radius(within, geoRadiusArgs);
List<GeoResult<RedisGeoCommands.GeoLocation<Object>>> geoResultList = geoResults.getContent();
Geo geo;
for (GeoResult<RedisGeoCommands.GeoLocation<Object>> geoResult : geoResultList) {
geo = new Geo();
geo.setObject(geoResult.getContent());
geo.setDistance(geoResult.getDistance().getValue());
geos.add(geo);
}
return geos;
}
}
3、初始化数据
选择一个经纬度坐标,插入40万个周边的坐标点数据
@Data
public class StoreBean {
private int id;
private String name;
private double[] loc;
private double dist;
}
public void insertRedisData(){
double longitude=114.068245;
double latitude=22.546195;
StoreBean storeBean;
for(int i=1;i<=100000;i++){
storeBean=new StoreBean();
storeBean.setId(i);
storeBean.setName("门店"+i);
double d=Double.parseDouble(i+"")/10000;
BigDecimal b1 = new BigDecimal(longitude+d);
BigDecimal