Can people near wechat also use redis( GEO)

Time:2021-5-13

I believe that the functions of people around wechat should have been used
Can people near wechat also use redis( GEO)
I can easily see people near me through my own positioning, and see the distance from that person to me. Have you ever thought about how to achieve this?

As a program, any problem should have a process of thinking, rather than looking at the conclusion directly. Next, we should think step by step until the problem is solved.

Get your place

People nearby are actually a kind of location comparison relationship, so the first step is to obtain their own location. Generally, the location is expressed by latitude and longitude. The acquisition of specific latitude and longitude depends on the client. As our back-end programmer, we can directly receive parameters, so the focus of this step is to use latitude and longitude to represent the location of each node, Friends who don’t know much about longitude and latitude can review the geography knowledge of middle school.

Solve the problem with the way of relational database (MySQL)

Let’s simplify the problem first. If all the people near me are immobile, that is to say, their positions are fixed. According to our traditional thinking, we save everyone’s longitude and latitude, and then traverse these longitude and latitude. We can get the distance between me and each longitude and latitude by some way, Then show the users within 5km from me

The specific implementation is as follows

Save everyone’s latitude and longitude as follows

user_id Longitude Latitude (latitude)
1 116.39 39.91
2 121.48 31.4
3 117.30 39.71

Traverse the data, compare with yourself, get the distance between everyone and yourself

By traversing all the records in the database and comparing the latitude and longitude of each record with its own latitude and longitude, the distance between each record and itself can be obtained.

How to get the distance between the two points according to the two longitudes and latitudes? I have a method on the Internet. You can refer to it

/**
 *Find the distance between two known longitudes and latitudes, in meters
 *
 *@ param lng1 $, lng2 longitude
 *@ param LAT1 $, lat2 latitude
 *@ return float distance, in meters
 * @author www.Alixixi.com
 */
function getdistance($lng1, $lat1, $lng2, $lat2) {
    //Change the angle to a fox degree
    $radLat1 = deg2rad($lat1); // The deg2rad() function converts angles to radians
    $radLat2 = deg2rad($lat2);
    $radLng1 = deg2rad($lng1);
    $radLng2 = deg2rad($lng2);
    $a = $radLat1 - $radLat2;
    $b = $radLng1 - $radLng2;
    $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6378.137 * 1000;
    return $s;
}

We want to get the data that the distance is less than 5km

Comparing the distances calculated last time, the data within 5km is the data of people nearby that we need.

Problems in using relational database (MySQL)

In fact, using MySQL seems to be able to solve the problem, but it is not

  • First of all, traversing the data is to traverse all the data, and it is in an interface that needs to return the results in time. This is very unscientific, and it is unrealistic if there are a lot of users
  • After traversing, we have to continue to calculate the distance, which is also a very large order of magnitude
  • From those are done, we have to filter again, in the vicinity, and again all the data traversal
  • If you meet the requirements of nearby people, you need to sort them according to the distance from near to far, and you have to traverse the calculation

The above method can be realized if the number of users is relatively small, but now mobile Internet companies generally have a large number of users, and the whole table traversal method can basically pass. So let’s look at a new scheme, which is implemented by redis Geo

Introduction to redis Geo

First of all, we need to note that redis geo is only available in version 3.2, so friends who need to use this function should remember to update the version of redis

In fact, redis geo has only six operation commands, so the basic idea comes out when you know these commands

  1. Geoadd: add the coordinates of a geographic location
  2. Geopos: get the coordinates of a geographic location
  3. Geodist: get the distance between two geographic locations
  4. Georadius: get the geographic location set within the specified range according to the given geographic location coordinates
  5. Georadiusbymember: get the geographic location set within the specified range according to the given geographic location
  6. Geohash: get the geohash value of a geographic location

For the above command, let’s take a look at the example directly, so that we can understand it more deeply

redis> GEOADD nearbyPeople 13.36 38.11 "user_1" 15.08 37.50 "user_2"
(integer) 2

For the above example, it is equivalent to that nearbypeople is a total key, user_ 1 and user_ 2 is equivalent to the two elements in nearbypeople and their corresponding longitude and latitude
In fact, the above example is to put the user_ 1 and user_ The latitude and longitude of 2 exist in the key “nearbypeople”

redis> GEOPOS nearbyPeople user_1 user_2
1) 1) "13.36138933897018433"
   2) "38.11555639549629859"
2) 1) "15.08726745843887329"
   2) "37.50266842333162032"

This is relatively simple, that is to get the element user in nearbypeople_ 1 and user_ 2 longitude and latitude of these two elements. Of course, if there is no longitude and latitude of the corresponding element of geoadd before, nil will be returned

redis> GEODIST nearbyPeople user_1 user_2
"166274.1516"
redis> GEODIST nearbyPeople user_1 user_2 km
"166.2742"
redis> GEODIST nearbyPeople user_1 user_2 mi
"103.3182"

Get user in nearbypeople_ 1 and user_ 2 the distance between the two nodes. The distance unit can be specified, as shown below

  • m: Meter, the default unit.
  • Km: km.
  • Mi: miles.
  • FT: feet.

Georadius is an important and core method with many parameters. Let’s refer to the document for details

GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]

Parameter Description:

  • m: Meter, the default unit.
  • Km: km.
  • Mi: miles.
  • FT: feet.
  • With dist: when returning the location element, the distance between the location element and the center is also returned.
  • With cool: returns the longitude and dimension of the location element together.
  • Withhash: in the form of a 52 bit signed integer, returns the ordered set score of the position element encoded by the original geohash. This option is mainly used for the underlying application or debugging, but it has little effect in practice.
  • Count limits the number of records returned.
  • ASC: the search results are sorted from near to far.
  • Desc: the search results are sorted from far to near.
redis>GEORADIUS nearbyPeople 15 37 200 km WITHDIST
1) 1) "user_1"
   2) "190.4424"
2) 1) "user_2"
   2) "56.4413"

The above command is to find out the elements within 200km from longitude and latitude (15,37) in nearbypeople, and carry the distance

Georadius by member has the same function as georadius, the only difference is that

Georadius is based on a certain latitude and longitude

Georadiusbymember is based on an element

Solving problems with redis Geo

In fact, the students who are familiar with the above command can solve this problem very well

First, we can refresh everyone’s position in the background to the geo object with nearbypeople as the key.

reids> GEOADD nearbyPeople 13.36 38.11 "user_1" 15.08 37.50 "user_2" .......

Because the location information of nearby people is also in nearby, it is obviously more appropriate to use geordius by member

GEORADIUSBYMEMBER nearbyPeople user_ n 5 km WITHDIST //user_ N is the user currently viewing nearby

This will solve our problems perfectly.