Spring Data Redis 教程

ReactiveGeoOperations 操作接口

Spring Data Redis 中,Geo 类型的响应式接口为 ReactiveGeoOperations,该接口定义的方法和 GeoOperations、BoundGeoOperations 接口定义的方法非常类似。

我们可以通过 ReactiveRedisTemplate 的 opsForGeo() 方法获取获取,代码如下:

ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();

添加坐标

  • reactor.core.publisher.Mono<Long> add(K key, Iterable<RedisGeoCommands.GeoLocation<M>> locations) 将 RedisGeoCommands.GeoLocations 添加到 key

  • reactor.core.publisher.Mono<Long> add(K key, Map<M,org.springframework.data.geo.Point> memberCoordinateMap) 将 memberCoordinateMap 中的坐标批量添加到 key

  • reactor.core.publisher.Mono<Long> add(K key, org.springframework.data.geo.Point point, M member) 将具有给定成员名称的 Point 添加到 key

  • reactor.core.publisher.Flux<Long> add(K key, org.reactivestreams.Publisher<? extends Collection<RedisGeoCommands.GeoLocation<M>>> locations) 将 RedisGeoCommands.GeoLocations 添加到 key

  • reactor.core.publisher.Mono<Long> add(K key, RedisGeoCommands.GeoLocation<M> location) 将 RedisGeoCommands.GeoLocation 添加到 key

示例:

@Test
public void add() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();

    // 成都天府广场坐标
    Point point = new Point(104.072206,30.663486);
    ops.add("key", point, "chengdu")
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) {
                    queue.add("添加成都坐标成功");
                }
            });
    System.out.println(queue.take());

    // 批量添加坐标
    Map<String,Point> pointMap = new HashMap<>();
    pointMap.put("beijing", new Point(116.403039,39.91513));
    pointMap.put("beijing2", new Point(116.303039,39.81513));
    ops.add("key", pointMap).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("批量添加坐标成功");
        }
    });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

添加成都坐标成功
批量添加坐标成功

删除键

  • reactor.core.publisher.Mono<Boolean> delete(K key) 删除给定的键

示例:

@Test
public void delete() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();

    // 成都天府广场坐标
    Point point = new Point(104.072206,30.663486);
    ops.add("key", point, "chengdu")
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) {
                    queue.add("添加成都坐标成功");
                }
            });
    System.out.println(queue.take());

    // 删除key
    ops.delete("key").subscribe(new Consumer<Boolean>() {
        @Override
        public void accept(Boolean aBoolean) {
            if(aBoolean) {
                queue.add("成功删除key");
            } else {
                queue.add("删除key失败");
            }
        }
    });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

添加成都坐标成功
成功删除key

测距

  • reactor.core.publisher.Mono<org.springframework.data.geo.Distance> distance(K key, M member1, M member2) 获取 member1 和 member2 之间的距离

  • reactor.core.publisher.Mono<org.springframework.data.geo.Distance> distance(K key, M member1, M member2, org.springframework.data.geo.Metric metric) 使用 Metric 单位获取 member1 和 member2 之间的距离

示例:

@Test
public void distance() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();
    // 批量添加坐标
    Map<String,Point> pointMap = new HashMap<>();
    pointMap.put("beijing", new Point(116.403039,39.91513));
    pointMap.put("chengdu", new Point(104.072206,30.663486));
    ops.add("key", pointMap).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("批量添加坐标成功");
        }
    });
    System.out.println(queue.take());

    // 计算成都和北京的距离
    ops.distance("key", "beijing", "chengdu")
        .subscribe(new Consumer<Distance>() {
            @Override
            public void accept(Distance distance) {
                queue.add("北京与成都距离:" + distance.getValue()
                        + distance.getMetric().getAbbreviation());
            }
        });
    System.out.println(queue.take());

    ops.distance("key", "beijing", "chengdu", Metrics.KILOMETERS)
        .subscribe(new Consumer<Distance>() {
            @Override
            public void accept(Distance distance) {
                queue.add("北京与成都距离:" + distance.getValue()
                        + distance.getMetric().getAbbreviation());
            }
        });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

批量添加坐标成功
北京与成都距离:1517797.1972m
北京与成都距离:1517.7972km

获取位置 Geohash

  • reactor.core.publisher.Mono<List<String>> hash(K key, M... members) 获取一个或多个成员的位置的 Geohash 表示

  • reactor.core.publisher.Mono<String> hash(K key, M member) 获取指定成员的位置 Geohash 表示

示例:

@Test
public void hash() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();
    // 批量添加坐标
    Map<String,Point> pointMap = new HashMap<>();
    pointMap.put("beijing", new Point(116.403039,39.91513));
    pointMap.put("chengdu", new Point(104.072206,30.663486));
    ops.add("key", pointMap).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("批量添加坐标成功");
        }
    });
    System.out.println(queue.take());

    // 获取成都的 Geohash
    ops.hash("key", "chengdu").subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) {
            queue.add(s);
        }
    });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

批量添加坐标成功
wm6n2np5f00

获取位置点表示

  • reactor.core.publisher.Mono<List<org.springframework.data.geo.Point>> position(K key, M... members) 获取一个或多个成员位置的点表示

  • reactor.core.publisher.Mono<org.springframework.data.geo.Point> position(K key, M member) 获取指定成员位置的点表示

示例:

@Test
public void position() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();
    // 批量添加坐标
    Map<String,Point> pointMap = new HashMap<>();
    pointMap.put("beijing", new Point(116.403039,39.91513));
    pointMap.put("chengdu", new Point(104.072206,30.663486));
    ops.add("key", pointMap).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("批量添加坐标成功");
        }
    });
    System.out.println(queue.take());

    // 获取成都位置点表示
    ops.position("key", "chengdu").subscribe(new Consumer<Point>() {
        @Override
        public void accept(Point point) {
            queue.add("x=" + point.getX() + ", y=" + point.getY());
        }
    });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

批量添加坐标成功
x=104.0722069144249, y=30.663486325924417

计算范围

利用这些方法可以获取根据一个点计算半径圆圈范围内的地理位置信息,方法如下:

  • reactor.core.publisher.Flux<org.springframework.data.geo.GeoResult<RedisGeoCommands.GeoLocation<M>>> radius(K key, org.springframework.data.geo.Circle within) 获取给定圈子边界内的成员。

  • reactor.core.publisher.Flux<org.springframework.data.geo.GeoResult<RedisGeoCommands.GeoLocation<M>>> radius(K key, org.springframework.data.geo.Circle within, RedisGeoCommands.GeoRadiusCommandArgs args) 应用 RedisGeoCommands.GeoRadiusCommandArgs 获取给定 Circle 边界内的成员。

  • reactor.core.publisher.Flux<org.springframework.data.geo.GeoResult<RedisGeoCommands.GeoLocation<M>>> radius(K key, M member, org.springframework.data.geo.Distance distance) 获取由成员坐标和给定半径应用公制定义的圆内的成员。

  • reactor.core.publisher.Flux<org.springframework.data.geo.GeoResult<RedisGeoCommands.GeoLocation<M>>> radius(K key, M member, org.springframework.data.geo.Distance distance, RedisGeoCommands.GeoRadiusCommandArgs args) 获取由成员坐标定义的圆内的成员,并应用 Metric 和 RedisGeoCommands.GeoRadiusCommandArgs 给定半径。

  • reactor.core.publisher.Flux<org.springframework.data.geo.GeoResult<RedisGeoCommands.GeoLocation<M>>> radius(K key, M member, double radius) 获取由成员坐标和给定半径定义的圆内的成员。

示例:

@Test
public void radius() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();
    // 添加多个坐标
    Map<String,Point> pointMap = new HashMap<>();
    pointMap.put("chengdu", new Point(104.07332,30.664768));
    pointMap.put("chengdudong_railway_station", new Point(104.145184,30.636433));
    pointMap.put("chengdubei_railway_station", new Point(104.145184,30.636433));
    pointMap.put("beijing", new Point(116.400739,39.920885));
    pointMap.put("wuhan", new Point(114.360454,30.588768));
    ops.add("key", pointMap).subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("批量添加坐标成功 " + aLong);
        }
    });
    System.out.println(queue.take());

    // 获取成都附近 100 公里范围内的地理位置
    Circle circle = new Circle(104.07332, 30.664768, 100*1000);
    ops.radius("key", circle).collectList()
            .subscribe(new Consumer<List<GeoResult<RedisGeoCommands.GeoLocation<String>>>>() {
                @Override
                public void accept(List<GeoResult<RedisGeoCommands.GeoLocation<String>>> geoResults) {
                    for(GeoResult<RedisGeoCommands.GeoLocation<String>> result : geoResults) {
                        RedisGeoCommands.GeoLocation<String> geo = result.getContent();
                        System.out.println(geo.getName());
                    }
                    queue.add("成都附近 100 公里范围内有" + geoResults.size() + "地理位置");
                }
            });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

批量添加坐标成功 5
chengdubei_railway_station
chengdudong_railway_station
chengdu
成都附近 100 公里范围内有3地理位置

删除坐标

  • reactor.core.publisher.Mono<Long> remove(K key, M... members) 删除指定的一个或多个坐标

示例:

@Test
public void remove() throws Exception {
    LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<>();
    ReactiveGeoOperations<String,String> ops = reactiveRedisTemplate.opsForGeo();

    // 成都天府广场坐标
    Point point = new Point(104.072206,30.663486);
    ops.add("key", point, "chengdu")
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) {
                    queue.add("添加成都坐标成功");
                }
            });
    System.out.println(queue.take());

    // 删除成都坐标
    ops.remove("key", "chengdu").subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) {
            queue.add("删除成都坐标成功 " + aLong);
        }
    });
    System.out.println(queue.take());
}

运行示例,输出结果如下:

添加成都坐标成功
删除成都坐标成功 1
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号