数据库
首页 > 数据库> > 关于mysql做距离筛选的两种方法

关于mysql做距离筛选的两种方法

作者:互联网

使用mysql自带的函数计算距离作为筛选条件

/**
*  @param :lat 纬度
*  @param :lon 经度
*  @param :dis 距离范围
**/
SELECT a.*,ROUND(6378.138 * 2 * ASIN(SQRT(POW(SIN((:lat * PI() / 180 - a.latitude * PI() / 180) / 2), 2) + COS(:lat * PI() / 180) * COS(a.latitude * PI() / 180) * POW(SIN((:lon * PI() / 180 - a.longitude * PI() / 180) / 2), 2))) * 1000) AS distance FROM maoyan_cinema a WHERE a.del_flag = 0 HAVING distance < :dis ORDER BY distance ASC

使用redis计算距离

//导入到redis部分代码
public void syncGeo() {
        //查询经度纬度主键id保存在list
        List<Object[]> list = xxx.getStationPoint();
        if (CollectionUtils.isEmpty(list) || list.size() < 1) {
            return;
        }
        Map<Long, Point> map = new HashMap<>(hashMapInitialCapacity);
        for (Object[] o : list) {
            map.put(Long.parseLong(o[0].toString()), new Point(Double.parseDouble(o[2].toString()), Double.parseDouble(o[1].toString())));
        }
        GeoOperations geoOperations = redisTemplate.opsForGeo();
        Long stations = geoOperations.geoAdd("redisKeyGeo", map);
        redisTemplate.expire("redisKeyGeo", 2, TimeUnit.DAYS);
    }
           Circle circle = new Circle(new Point("入参经度", "入参纬度"), new Distance("距离范围", Metrics.KILOMETERS));
            //这里限制1w条,可根据实际业务确定需要多少条数据
            RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().sortAscending().limit(10000);
            GeoResults<RedisGeoCommands.GeoLocation<Integer>> results = geoOperations.geoRadius("redisKeyGeo", circle, args);
            Map<Long, Double> stationIdsAndDistance = new LinkedHashMap<>();
            List<GeoResult<RedisGeoCommands.GeoLocation<Integer>>> content = results.getContent();

标签:redis,list,距离,180,mysql,new,筛选,PI,主键
来源: https://www.cnblogs.com/zhangjiangwen/p/16054834.html