1. ホーム
  2. データベース
  3. レディス

redisを使ってnearly peopleの機能を実装する

2022-01-15 08:03:24

プリアンブル

{Redis はバージョン 3.2 から GEO (geograph) 機能を提供するようになりました。 Redisはバージョン3.2以降、ジオロケーション関連の操作にGEO(ジオグラフ)機能を提供し、近所に人がいるなどのジオロケーションに依存した機能を実現することができるようになりました。

ツール

百度緯度・経度ピッカー

ピックアップ座標系

I. テストデータ

<ブロッククオート

120.70012 28.00135 温州市
/{br 120.207686 30.253359 杭州
121.482537 31.238034 上海
118.793117 32.068407 南京市

II. 基本コマンド

1.ジオアド

ジオロケーション関連の操作を行うには、まず特定の地理的位置を記録する必要がありますが、これは次のような形式でgeoaddコマンドを実行することで行えます。

GEOADD set name latitude longitude latitude name [longitude latitude name...]
//add set
geoadd citys 120.70012 28.00135 wenzhou 120.207686 30.253359 hanghzou

追加されたコレクションを見る

2.ジオポス

このコマンドは、入力された地名に基づいてその場所の情報座標を取得するもので、次のような構文で実行します。

GEOPOS set name location [name...]
geopos address wuyue

座標情報を見る

3.ジオディスト

このコマンドは、次の構文で2つの位置の距離を計算するために使用されます。

geodist set name location1 location2 [unit]
// Calculate the distance between Hangzhou and Nanjing
geodist citys hanghzredis:0>ou nanjing km

オプションのパラメータ:unitは、距離を計算する単位を指定するためのもので、その値は以下のいずれかになります。

m :メートルを示す

km:キロメートルを表す

mi:マイルを表します。

ft:フィートを表します。

4.ジオラディウス

georadiusは、範囲を計算する際に、ユーザーが指定した緯度と経度を中心点として、その

georadius set name precision latitude radius m|km|ft|mi| [WITHCOORD] [WITHDIST] [ASC|DESC] [COUNT count]
// Search for cities within 100km of me
georadius citys 120.754274 27.983296 100 km

半径:距離

WITHCOORD: 座標を返す

はバージョンの関係で空かもしれません

WITHDIST:距離も返す

ASC|DESC:ソート

count: どれくらいの長さを取るか

5. georadiusbymember

georadiusbymember は、ロケーションセットに格納されている位置をセントロイドとして使用します。

georadiusbymember address set location name distance units
//search for locations within 5 km of wuyue
georadiusbymember address wuyue 5 km

III. javaApi

エンティティクラス

package com.jiale.web.controller.pojo;
 
import lombok.Data;
 
import java.io;
 
/**
 * @Author: Hello World
 * @Date: 2021/9/16 16:12
 * @Description:
 *@Data
public class AddressInfo implements Serializable {
 
    /** Name of the network *    private String title;
    /* Address of the network *    private String address;
    /** contact information of the network *    private String phone;
    /** dot-site coordinates-accuracy**    private double x;
    /** dot-site coordinates - latitude *    private double y;
}

package com.jiale;
 
import com.jiale.common.config.JialeGlobal;
import com.jiale.web.controller.pojo.AddressInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
 
import java.math.BigDecimal;
import java.util.List;
 
 
/**
 * @Author: Hello World
 * @Date: 2021/9/15 17:47
 * @Description:
 *@SpringBootTest
public class JialeTests {
 
    @Autowired
    RedisTemplate redisTemplate;
 
   @Test
    public void test1(){
        System.out.println(JialeGlobal.getUploadPath());
    }
 
    /**
     * I. Add location information to redis
     * 1. webstore-location-information-geo
     * 2. outlet-detail
     *    @Test
    public void geoAdd(){
        // 1. outlet location information storage 120.653208,28.032606
        Point point = new Point(120.653208, 28.032606);
        redisTemplate.boundGeoOps("outlets").add(point,"江心屿");
        //2. Network details
        AddressInfo addressInfo = new AddressInfo();
        addressInfo.setTitle("江心屿");
        addressInfo.setAddress("Jiangxinyu scenic area in Lucheng District, Wenzhou City, Zhejiang Province");
        addressInfo.setPhone("(0577)88201281");
        addressInfo.setX(120.653208);
        addressInfo.setY(28.032606);
        redisTemplate.boundHashOps("outletsInfo").put("江心屿",addressInfo);
    }
 
    /**
     * II. Get the location coordinate information
     *    @Test
    public void geoPos(){
        // Pass in the location name to query the location information
        List<Point> position = redisTemplate.boundGeoOps("outlets").position("South Pond Five Cluster");
        for (Point point : position) {
            System.out.println(point);
        }
    }
 
    /**
     * III. Calculate two location information
     *    @Test
    public void geoDist(){
        /**
        Distance distance = redisTemplate.boundGeoOps("outlets").distance("JiangxinYu", "WenzhouLand");
        /        double value = distance.getValue();
        /        String unit = distance.getUnit();
        System.out.println("Distance between two points:"+value+unit);
         *        //show in km
        /**
        Distance distance = redisTemplate.boundGeoOps("outlets").distance("江心屿", "温州乐园", Metrics.KILOMETERS);
        /        double value = distance.getValue();
        /        String unit = distance.getUnit();
        System.out.println("Distance between two points:"+value+unit);* 
        // keep two decimal places
        Distance distance = redisTemplate.boundGeoOps("outlets").distance("江心屿", "温州乐园", Metrics.KILOMETERS);
        /        double value = distance.getValue();
        /        String unit = distance.getUnit();
        System.out.println("Distance between two points:"+new BigDecimal(value).setScale(2,BigDecimal.ROUND_HALF_UP) +unit);
    }
 
    /**
     * IV. Find the location of the specified range according to the given latitude and longitude
     *    @Test
    public void geoRadius(){
        // Specify the location
        Point point = new Point(120.754274, 27.983296);
        // build condition - 10km
        Distance distance = new Distance(10, Metrics.KILOMETERS);
        Circle circle = new Circle(point,distance);
        /        GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
         //Include location information
        args.includeDistance();
 
        //stores the location information of the queried URL
        GeoResults<RedisGeoCommands.GeoLocation<String>> outlets = redisTemplate.boundGeoOps("outlets").radius(circle, args);
        for