Introduction to the

Bitmaps, HyperLogLog and Geospatial are three special data types of Redis, among which Bitmaps cannot be regarded as a data type strictly speaking. Bitmaps, HyperLogLog and Geospatial can easily solve many problems, which are also the knowledge points often studied in interviews of large factories. The following details the principle and use of Bitmaps, HyperLogLog and Geospatial. If you need it, you can connect it with one key. If you have any questions, please leave a message and reply in time.

A, Bitmaps

1, the introduction of

Bitmaps are called Bitmaps and are not a data type. Many video tutorials online refer to Bitmaps as data types, which is probably incorrect. Bitmaps are “data types” that Redis provides to users to manipulate bits. It mainly has the following basic characteristics:

  • Bitmaps are not data types. They are basically key-values and byte arrays. We can get and set the contents of the bitmap directly using the ordinary GET /set bitmap, or we can treat byte arrays as “bit arrays” through the bitmap operations provided by Redis, such as getbit/setbit
  • Bitmaps’ “bitarray” can only store zeros and ones per cell, and the subscripts of the arrays are called offsets in Bitmaps
  • Setting Bitmaps without a key automatically generates a new string, and if the offset is set beyond the range of existing content, the bitarray is automatically expanded to zero

Bitmaps.png

2. Basic operations

2.1 SETBIT key offset value

For strings stored in key, sets or clears bits at the specified offset, depending on the value argument, 0/1. When the key does not exist, a new string is automatically generated. The string is stretched to ensure that the value is stored at the specified offset. When the string is stretched, the whitespace is filled with zeros. Time complexity:

O(1)

Offset range:

0 ~ 2 ^ 32

The return value:

Specifies the bits that the offset originally stored

Example: Using Bitmaps to store whether the user clocked in, clocked in as 1, not clocked in as 0, user ID as offset suppose there are 10 users, users 1, 3, 5, 9, 10 clocked in, others did not clocked in, Bitmaps initialization result is as follows: \

Clock :20210806 represents the clock record \ of 2021/08/06

Matters needing attention: In a formal system, the id will not be 0, 1, or 2, but will start with an array, such as 1000000000000001, 1000000000000002, which is very easy to waste offsets, so we can consider calculating and subtracting an appropriate value before setting offsets. If the Bitmaps offset is too large, it will take too long to allocate memory and the Redis server will block.

2.2 GETBIT key offset

Gets the bit at the specified offset. If offset is greater than the length of the string, or if key does not exist, 0 is returned. Time complexity:

O(1)

Return value: string value Specifies the bit at the offset. Example: clock:20210806 represents the clocking record \ of 2021/08/06



2.3 BITCOUNT key [start] [end]

Counts the number of bits in the given string that are set to 1. The start and end arguments specify the scope of the query and can use negative values. -1 represents the last byte and -2 represents the second byte. Note: Start and end are byte indexes, so each increment of 1 represents an increment of one character, that is, 8 bits, so the query range of bits must be a multiple of 8. Time complexity:

O(N)

Return value: the number of bits set to 1 Example: clock:20210806 represents the clock record of 2021/08/06. At this time, there are 11 bits in total, the first 8 bits have 3 ones, and the last 3 bits have 2 ones \

Bitcount clock:20210806 0 0 Indicates the number of 1s in the first character. bitcount clock:20210806 1 1 Indicates the number of 1s in the second character. bitcount clock:20210806 0 1 Denotes the number of 1 \ in the first and second characters



2.4 BITPOS key bit [start] [end]

By default, the entire Bitmaps can be detected. You can also specify the range of Bitmaps by using the start and end arguments. Note: Start and end are byte indexes, so each increment of 1 represents an increment of 8 bits, so the range of Bitmaps must be a multiple of 8. Time complexity:

O(N)

Return value: integer Bitpos clock:20210806 0 indicates the position of the first 0. Bitpos clock:20210806 1 indicates the position of the first 1. 1 1 1 indicates the position of the first 1 in the second character. Bitpos clock:20210806 10 1 indicates the position of the first 1 in the first and second characters

imagepng


2.5 BITOP operation destKey Key [key…]

Redis Bitmaps provides BITOP instructions to operate on one OR more binary keys (except for the NOT operation). The result of the operation is saved to destkey. Operation is the operation type, AND there are four types: AND, OR, NOT, XOR

  • BITOP AND destkey Key [key… , obtains a logical union for one or more keys, and saves the result to destkey
  • BITOP OR destkey key [key… To obtain logical or for one or more keys and save the result to destkey
  • BITOP XOR destKey Key [key…] To obtain logical XOR for one or more keys and save the result to the Destkey
  • BITOP NOT destKey Key Specifies the logical no of the given key and saves the result to the destkey

When the length of the string is inconsistent, the missing part of the shorter string is treated as a 0, and the empty key is treated as the time complexity of the string sequence containing 0:

O(N)

Return value: result of bit operation (the length of the string saved to destkey is equal to the length of the longest string in the input key) Example: here use key1 1001 and key2 1011 for the above four operations \

BITOP AND destkey Key [key… Operation rules: 0&0=0; 1 = 0 0 &; 1 & 0 = 0; 1 &1 = 1; That is, if both of them are “1”, the result is “1”; otherwise, 0\

BITOP OR destkey key [key… Algorithm: 0 | 0 = 0; 0 | 1 = 1; 1 | 0 = 1; 1 | 1 = 1; That is, if either of the two objects participating in the operation is 1, the value is 1\

BITOP XOR destKey Key [key…] Operation rule: 0^0=0; 0 ^ 1 = 1; 1 ^ 0 = 1; 1 ^ 1 = 0; That is, if the two corresponding bits of the two objects participating in the operation are “different” (different values), the result of that bit is 1, otherwise, 0\

BITOP NOT destKey Key operation rule: Set the value invert \

2.6 BITFIELD key [GET type offset] [the SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP | | SAT FAIL]

Both setbit and getbit in 2.1 and 2.2 operate on a single bit of the specified key. If multiple bits need to be operated simultaneously, the bitfield instruction can be used. Bitfield has three sub-instructions, namely GET, set and incrby, which can read and write the specified fragment. However, a maximum of 64 consecutive bits are processed. More than 64 consecutive bits require the use of multiple subinstructions, and bitfield can execute multiple subinstructions at the same time (unsigned integers can only return 63 bits).

Note:

  • Use the GET subcommand to access bits outside the current range of the string (including if the key does not exist). The value of the bits outside the range is treated as 0.
  • Using the SET subcommand or the INCRBY subcommand to access bits beyond the current range of the string causes the string to be enlarged, and the enlarged bits are padded with bits with a value of 0. When extending a string, the command calculates the minimum length required to perform the operation based on the farthest bits of the string that are currently available.

Value operation subinstruction:

  • GET – Returns the specified range of bits
  • SET – Sets the specified range of bits and returns its old value
  • INCRBY – Performs addition on the specified range of bits and returns its old value. The user can implement subtraction by passing a negative value to the increment parameter

Overflow policy subdirective:

  • WRAP: WRAP around – The default overflow strategy. For unsigned integers, wrapping is like performing a modulo calculation using the value itself and the largest unsigned integer that can be stored. This is also standard behavior in C. For signed integers, an overflow causes the number to be reevaluated from the smallest negative number, while an underflow causes the number to be reevaluated from the largest positive number.
  • SAT: saturation calculation can also be understood as saturation truncation. In this mode, the result of underflow calculation is the smallest integer value, while the result of overflow calculation is the largest integer value
  • FAIL: This mode rejects computations that cause overflows or underflows and returns nil to indicate that the computations were not performed.

Note that the OVERFLOW subcommand will only have an effect on the INCRBY command executed immediately after it until the next OVERFLOW command is executed with it. By default, the INCRBY command uses WRAP to handle overflow calculations. I and u: I indicates a signed integer, and u indicates an unsigned integer. U4 represents a 4-bit unsigned integer and I8 represents an 8-bit signed integer.

Example: Test number is 10100111\

Bitfield key get u4 0 Take 4 bits from the first bit and get the unsigned number 1010=10\

Bitfield key set u8 0 128 replaces the next 8 bits with an unsigned integer 128, i.e. 10000000\

Bitfield key incrby u4 2 1 The next 4 unsigned digits +1\ from the second digit

Bitfield key set u8 0 128 GET U4 0 incrby u4 2 1

Second, the HyperLogLog

1, the introduction of

Let’s start with a business question: Suppose your product manager asked you to design a module to measure PV (Page View views), what would you do? I think many people for PV (Page View Page views) statistics will quickly think of using Redis incR, incrby instructions, to configure a separate Redis counter for each Page, add the technical area key suffix when its date, such a request comes, All PVS can be counted by executing incR and IncrBY instructions.

When you complete this requirement, the product manager asks you to design a module that counts UV (Unique Visitor). What do you do? UV is not the same as PV, UV needs to be de-weighted according to the user ID. If the user does not have an ID, we may need to consider using the IP that the user accesses or some other unique flag that the front end passes. At this point, you may want to use the following scheme to count UV.

  1. The distinct count is used to count the number of non-duplicates in a MySQL database table
  2. Use Redis data structures such as set, hash, and bitmaps for storage. For example, if we use set, we can use the user ID and join the set through sadd

But there are two big problems with both proposals:

  1. As the amount of data increases, the space used to store data becomes larger and larger. UV statistics for very large pages are basically impractical
  2. The performance of statistics is slow. Although statistics can be collected asynchronously, the performance is not ideal

Therefore, for UV statistics, we will consider using Redis’s new data type HyperLogLog. HyperLogLog is an algorithm used for radix statistics, which provides an imprecise de-counting scheme (the imprecision is not very imprecise), with a standard error of 0.81%. Such an error range is allowed for UV statistics. The advantage of HyperLogLog is that the storage space for cardinality calculations is fixed when the number or volume of input elements is very large. In Redis, each HyperLogLog key costs only 12KB of memory to compute close to 2^64 different cardinals. However: HyperLogLog can only count the size of the cardinality (that is, the size of the data set, the number of sets), it cannot store the element itself, it cannot store the element itself like a set, that is, it cannot return the element.

HyperLogLog instructions all begin with PF (PF), this is because the inventor of HyperLogLog was Philippe Flajolet, pf is his initials.

2, the command

PFADD key element [Element…]

Add any number of elements to the specified HyperLogLog when PFADD key element [element… When the command is executed, the command returns 1 if the estimated approximate cardinality of the HyperLogLog has changed since the command was executed. Otherwise, 0 is returned. If the given key does not exist when the HyperLogLog command is executed, an empty HyperLogLog structure is created before the command is executed. This command can be used to give only the key to element, and when called this way:

  • If the given key exists and is already a HyperLogLog, this call has no effect
  • If the given key does not exist, the command breaks into an empty HyperLogLog and returns 1 to the client

Return value: 1 if the data stored inside the HyperLogLog data structure has been modified, 0 otherwise

Time complexity: O(1)

Example: \

2.2 PFCOUNT key [key…]

The PFCOUNT command can be followed by multiple keys, when the PFCOUNT key [key… The HyperLogLog command, when applied to a single key, returns the approximate cardinality of the HyperLogLog stored in the given key, or 0 if no key exists; When PFCOUNT key [key…] When applied to multiple keys, the command returns the approximate cardinality of the union of the given HyperLogLog, calculated by merging the index of the given HyperLogLog into a temporary HyperLogLog.

Return value: Returns the approximate integer value of the number of unique elements contained in a given HyperLogLog

Time complexity: When the command is applied to a single HyperLogLog, the time complexity is O(1) and has a very low average constant time. When the command is applied to N Hyperloglogs, the time complexity is O(N), and the constant time is much larger than that of a single HyperLogLog.

Example: \

2.3 PFMERGE destkey sourcekey [sourcekey…]

After merging multiple HyperLogLog into one HyperLogLog, the cardinality of the merged HyperLogLog is close to the union of all the visible sets of the input HyperLogLog. The HyperLogLog obtained after merging will be stored in the destkey. If the key does not exist, Before the command is executed, an empty HyperLogLog is created for the key.

Return value: String reply, returns OK

Time complexity: O(N), where N is the number of HyperLogLog to be merged, but the constant complexity of this command is high

Example: \

3, the principle of

3.1 Bernoulli test

HyperLogLog algorithm design can use 12K memory to approximate statistics of 2^64 data, this and Bernoulli test has a great relationship, so before exploring the principle of HyperLogLog, we need to know Bernoulli test first.

The following is the introduction of Bernoulli’s experiment on Baidu Baike:

A Bernoulli experiment is a randomized trial conducted repeatedly and independently of each other under the same conditions, characterized by only two possible outcomes: occurrence or non-occurrence. We assume that this experiment is independently repeated n times, then we call this series of repeated independent randomized trials n-heavy Bernoulli tests, or Bernoulli scenarios. Individual Bernoulli experiments don’t make a lot of sense. However, when we run Bernoulli experiments over and over again to see how many of them are successful and how many are not, it does, and the cumulative record contains a lot of potentially very useful information.

The Bernoulli test is part of the theory of data probability, and its allusion comes from “flipping a coin”. There’s only heads and tails on a coin, and there’s a 50% chance that every flip of the coin comes up heads, and we keep flipping the coin until we get the first heads, and we keep counting the number of flips, and that’s called a Bernoulli test. Bernoulli tests need to be done a very large number of times before the data becomes meaningful. For n Bernoulli trials, a positive for n times, assume that each time the number of Bernoulli trials throwing for k (that is, every time a positive throwing the number of times), the first times as Bernoulli trials throwing k1, the NTH Bernoulli trial casting number to kn, in the NTH Bernoulli trials, throwing a maximum number of kmax. The above Bernoulli test, combined with the maximum likelihood estimation method (maximum likelihood estimation), obtained the estimation relationship between n and kmax: n=2^kmax. It is obvious that this estimation relationship is not accurate, for example, in the following case: in the first trial: heads appear on the first flip, k=1,n=1; The second experiment: 3 flips produced heads, k=3,n=2; The third experiment: 6 flips of heads, k=6,n=3; N test: k=10,n=n, n=2^10,n= 2^10,n= 2^10,n= 2^10,n= 2^10,n= 2^kmax,n= 2^6 ≠3 Therefore, it is concluded that the estimation method has a large error.

3.2 Optimization of valuation

As for the above large valuation deviation, the following methods can be combined to narrow the error:

  1. Increase the number of rounds of testing and average them. Assuming that the three Bernoulli tests are one round of tests, we take the largest kmax in this round of tests as the data of this round of tests, and set the number of test rounds to 100, so that in 100 rounds of experiments, we will get 100 kmax, and the average is (k_max_1 +… + k_max_m)/m, where M is the number of test rounds and 100.
  2. Add the correction factor, which is an unfixed value and can be adjusted according to the actual situation.

The above method of increasing the number of test rounds and removing the average value of Kmax is the realization of LogLog algorithm. Thus LogLog its estimation formula is as follows: \



HyperLogLog differs from LogLog in that HyperLogLog uses harmonic means, not averages. The harmonic mean is the mean of the reciprocal(Harmonic mean). Compared with the average, the harmonic average can reduce the influence of the maximum on the average. This is just like me and Ma’s father calculating the average salary together. If we use the average, we will also get a salary of billions, which is definitely not reasonable.

The mean and harmonic mean were calculated as follows:

Assuming that my salary is 20000 and Jack Ma 1000000000, the average is calculated as follows: (20000 + 1000000000) / 2 = 500010000 2/(1/20000 + 1/1000000000) ≈ 40000 Obviously, the average monthly salary of 40000 is more in line with the actual average, 500 million is unrealistic.

The basic formula for calculating the harmonic mean is as follows: \



3.3 Implementation of HyperLogLog

According to 3.1 and 3.2, we can roughly know the implementation principle of HyperLogLog. The main essence of HyperLogLog is to estimate the number n of random numbers by recording the maximum length K of the low continuous zero bit (also known as kmax above).

Any value in computer we can convert them into bit string, which is composed of 0 and 1 bit array, we start from the bit string of low computation, until the first one, it’s like the Bernoulli trials above flip a coin, flip a coin until a first positive so far (except the number is 0 and 1, There is no difference between heads and tails of the coins used in Bernoulli’s experiment). The number of random numbers HyperLogLog estimates, such as our UV count, is like the number of Bernoulli trials.

To sum up, the implementation of HyperLogLog is mainly divided into three steps: Step 1: Convert the input data into bit string Through the hash function, 0 and 1 in the bit string can be analogous to the heads and tails of coins, which is the first and second step to realize the valuation statistics: Points barrel barrel is above 3.2 points several rounds of valuation optimization, do the benefits of such valuations can be more accurate. In the computer, buckets are divided into m groups by a large array S with the unit of bit and length of L. The value of M is the number of rounds and the number of bits occupied by each group is the same, set as P. The following relationship is obtained:

  • L = S.length
  • L = m * p
  • Memory of array S = L / 8/1024 (KB)

In HyperLogLog, we know that it needs 12KB of memory to do cardinality statistics, because in HyperLogLog, m=16834, P =6, L=16834 * 6, so =16834 * 6/8/1024 = 12 (KB). The reason why 6 bits is used to store Kmax is because 6 bits can store a maximum of 64 bits. Today’s computers are all 64-bit or 32-bit operating systems, so 6 bits is the most memory efficient and meets the demand. \

Step 3: Bucket allocation is all about how to allocate buckets for different data. We get string bits by calculating the hash. As long as the hash function is good enough, it’s hard to create hash collisions. The same value yields the same hash value (this is also a key point HyperLogLog can use for UV statistics). In this case, we need to calculate the value in the bucket. We can calculate the value in many ways, such as the lower 16 bits of the value as the bucket index value, or using value modulo, etc.

3.4 Code Implementation -BernoulliExperiment

First, write a verification of the estimated value of Bernoulli test n=2^kmax in 3.1. The relative deviation of the estimated value is relatively large, and the deviation of the estimated value will decrease to a certain extent when the number of test rounds increases. The code example is as follows:

package com.lizba.pf; import java.util.concurrent.ThreadLocalRandom; /** * <p> * The relationship between cardinality n and kmax in Bernoulli test n = 2^kmax * </p> ** @author: Liziba * @date: 2021/8/17 23:16 */ public class BernoulliExperimentTest {static class BitKeeper {** * Record the maximum length of a low 0 */ private int kmax; Public void the random () {/ / generates random Numbers long value = ThreadLocalRandom. The current () nextLong (2 l < < 32); int len = this.lowZerosMaxLength(value); if (len > kmax) { kmax = len; }} / calculating the length of the low 0 * * * * here if you don't understand look under my comment * value > > I said it would value moves to the right I, 1 < = I < 32, will be removed from the low value < < * I said it will value the left I, 1 < = I < 32, If the value value is 0 and the right value is removed, the left value is replaced by the left value. If the value value is 0 and the right value is removed, the left value is replaced by the left value, then the value of the value will change. * * @param value * @return */ private int lowZerosMaxLength(long value) {int I = 1; for (; i < 32; i++) { if (value >> i << i ! = value) { break; } } return i - 1; }} static class Experiment {/** test n */ private int n; private BitKeeper bitKeeper; public Experiment(int n) { this.n = n; this.bitKeeper = new BitKeeper(); } public void work() { for(int i = 0; i < n; i++) { this.bitKeeper.random(); }} /** * output the number of tests in each round n * output logn/log2 = k = 2^k = n, where k is our estimated kmax * output kmax, */ public void debug() {system.out.printf ("%d %.2f %d\n", this.n, math.log (this.n)/math.log (2), this.bitKeeper.kmax); } } public static void main(String[] args) { for (int i = 0; i < 100000; i++) { Experiment experiment = new Experiment(i); experiment.work(); experiment.debug(); }}}Copy the code

We can modify the main function, test the number of rounds, and then according to the output result, n=2^kmax is relatively consistent. \

3.5 code implementation -HyperLogLog

Next, according to HyperLogLog using harmonic mean + bucket to do code optimization, simulation of a simple version of HyperLogLog algorithm implementation, the code is as follows:

package com.lizba.pf; import java.util.concurrent.ThreadLocalRandom; /** * <p> ** @author: Liziba * @date: 2021/8/18 10:40 */ public class HyperLogLogTest {static class BitKeeper {** * private int kmax; Kmax ** @param value */ public void random(long value) {int len = this.lowZerosMaxLength(value);  if (len > kmax) { kmax = len; }} / calculating the length of the low 0 * * * * here if you don't understand look under my comment * value > > I said it would value moves to the right I, 1 < = I < 32, will be removed from the low value < < * I said it will value the left I, 1 < = I < 32, If the value value is 0 and the right value is removed, the left value is replaced by the left value. If the value value is 0 and the right value is removed, the left value is replaced by the left value, then the value of the value will change. * * @param value * @return */ private int lowZerosMaxLength(long value) {int I = 1; for (; i < 32; i++) { if (value >> i << i ! = value) { break; } } return i - 1; } } static class Experiment { private int n; private int k; Private BitKeeper[] keepers; /** BitKeeper[] keepers; public Experiment(int n) { this(n, 1024); } public Experiment(int n, int k) { this.n = n; this.k = k; this.keepers = new BitKeeper[k]; for (int i = 0; i < k; i++) { this.keepers[i] = new BitKeeper(); }} /** * (int) (((m & 0xfff0000) >> 16) % keepers.length) -> calculate the current index of m in the keepers array * 0xfff0000 is a binary low 16-bit hexadecimal number with all zeros, Its binary number is - > 1111111111110000000000000000 * m & zero xfff0000 can factoring m high 16, (m & 0 xfff0000) > > 16 then moves to the right 16, so we can remove the low 16 bits, * ((m & 0xfff0000) >> 16) % keens. length Public void work() {for (int I = 0; i < this.n; i++) { long m = ThreadLocalRandom.current().nextLong(1L << 32); BitKeeper keeper = keepers[(int) (((m & 0xfff0000) >> 16) % keepers.length)]; keeper.random(m); }} @return */ public double estimate() {double sumBitsInverse = 0.0; For (BitKeeper keeper: keepers) {sumBitsInverse += 1.0 / (float) keeper.kmax; } double avgBits = (float) keepers.length / sumBitsInverse; return Math.pow(2, avgBits) * this.k; Public static void main(String[] args) {for (int I = 100000; i < 1000000; i+=100000) { Experiment experiment = new Experiment(i); experiment.work(); double estimate = experiment.estimate(); Printf ("%d %.2f %.2f\n", I, estimate, Math.abs(estimate - i) / i); }}}Copy the code

The test results are as follows, the error is basically controlled below 0.08, or very high error, so the algorithm is very rough

Third, Geospatial

1, the introduction of

Geospatial is a GEO module added by Redis after version 3.2. This module can be used to realize location functions such as people near wechat, online ordering and “nearby restaurant”.

2, the command

2.1 GEOADD

Command Introduction:

GEOADD Key Longitude Latitude Member [Longitude Latitude Member…]



The given spatial element (dimension, longitude, name) is added to the specified key, and the data is stored in the key as an ordered collection. The parameters that GEOADD receives must be entered first for longitude and then for dimension.

The GEOADD latitude and longitude input ranges are as follows (poles are not supported) :

  1. The effective longitude is between -180° and 180°
  2. The valid dimensions range from -85.05112878° to 85.05112878°

When the user tries to enter an out-of-range longitude or latitude, the GEOADD command returns an error.

Code example: You can add elements of a single location in sequence or at the same time.

127.0.0.1:6379> geoadd city 116.405289 39.904987 beijing
(integer) 1
127.0.0.1:6379> geoadd city 117.190186 39.125595 tianjin
(integer) 1
127.0.0.1:6379> geoadd city 121.472641 31.231707 shanghai
(integer) 1
127.0.0.1:6379> geoadd city 112.982277 28.19409 changsha 113.28064 23.125177 guangzhou
(integer) 2
Copy the code

Examples of errors:

127.0.0.1:6379> geoadd city 190 18 buzhidao
(error) ERR invalid longitude,latitude pair 190.000000,18.000000
Copy the code

2.2 GEOPOS

Command Introduction:

GEOPOS key member [Member…]

GEOPOS takes the position (longitude and latitude) of the element in a given position based on the key. GEOPOS can accept either one member or multiple members, and returns nil if none exists

Code examples:

127.0.0.1:6379> Geopos Beijing (empty array) 127.0.0.1:6379> Geopos city Beijing 1) 1) Geopos city Tianjin Shanghai 1) 1) "geopos city Tianjin Shanghai 1) 1)" 2) Geopos city Xiaoriben 1) 1) 1) "1) "2) "1) "1)" (nil)Copy the code

image.png

2.3 GEODIST

Command Introduction:

GEODIST key member1 member2 [unit]

Returns the distance between two given positions as a double – precision floating-point number. If one of the given locations does not exist (and neither exists, as shown in the example below), nil is returned.

Unit Description:

  • M – > m
  • Km – > km
  • Mi – > miles
  • Ft – > feet

Default unit: if the user does not specify a unit, the default is meters (m).

Margin of error: The GEODIST algorithm considers the Earth as a complete sphere, with a maximum margin of error of 0.5% in the limiting case

Code examples:

127.0.0.1:6379> geodist city beijing shanghai m
"1067597.0432"
127.0.0.1:6379> geodist city beijing shanghai km
"1067.5970"
127.0.0.1:6379> geodist city beijing xiaoriben
(nil)
127.0.0.1:6379> geodist city meiguoguizi xiaoriben
(nil)
Copy the code

2.4 GEORADIUS

Command Introduction:

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

Returns all of the location elements contained by the key that are within a given maximum distance from the center, centered at a given latitude and longitude.

M | km | ft | mi options:

  • M – > m
  • Km – > km
  • Mi – > miles
  • Ft – > feet

[WITHCOORD] [WITHDIST] [WITHHASH]

  • [WITHCOORD] : Returns the latitude and longitude of the positional element.
  • [WITHDIST] : Returns the location element and the distance between the location element and the center. The units of distance are the same as the units of range given by the user.
  • [WITHHASH] : Returns the original Geohashed ordered set score of the positional element as a 52-bit signed integer. This option is mainly used for low-level applications or debugging, and is not useful in practice.

[ASC | DESC] options:

  • ASC: Returns position elements from near to far based on a given central position
  • DESC: Returns the location element from far to near based on the given central location

The [COUNT COUNT] argument: GEORADIUS returns all positional elements that meet the criteria by default. However, the user can specify the first N matching elements with the [COUNT COUNT] parameter. This parameter reduces the number of elements that need to be returned, somewhat reducing bandwidth stress.

Return value: The return value of GEORADIUS is an array, but the contents of the array change depending on the presence or absence of the above parameters

  • If no WITH argument is given, the plain linear list is returned
  • Given parameters such as [WITHCOORD] [WITHDIST] [WITHHASH], return a two-layer nested array

Please refer to the following example for the specific return value. It is recommended that you do it several times

Code example: No WITH argument given

127.0.0.1:6379> georadius city 116.405289 39.904987 1000 km
1) "tianjin"
2) "beijing"
Copy the code

Given parameters such as [WITHCOORD] [WITHDIST] [WITHHASH], return a two-layer nested array

127.0.0.1:6379> Georadius City 116.405289 39.904987 1000 km withCoord 1) 1) "tianjin" 2) 1) 1)" "39.12559461779084558" 2) 1) 1) "116.40528827905654907" 2)"Copy the code
Dist 1) 1) 1) "tianjin" 2) "Tianjin" 2) 1) "Beijing" 2) "0.0001"Copy the code

2.5 GEORADIUSBYMEMBER

Command Introduction:

GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]

The difference between GEORADIUSBYMEMBER and GEORADIUS is that GEORADIUSBYMEMBER does not need to set the latitude and longitude, but only needs to set the key of the member, and the specific use is the same as GEORADIUS

Code examples:

127.0.0.1:6379> GeoradiusbyMember City Beijing 1000km 1) "tianjin" 2) "Beijing"Copy the code
127.0.0.1:6379> GeoradiusbyMember City Beijing 1000km withCoord 1) 1) "tianjin" 2) 1)" "39.12559461779084558" 2) 1) 1) "116.40528827905654907" 2)"Copy the code

2.6 GEOHASH

Command name:

GEOHASH key member [member…]

Returns a GeoHash representation of one or more positional elements, which can be given as many as members of keys, thus returning an array.

Code examples:

Geohash City Beijing Shanghai changsha 1) "wx4g0b7xru0" 2) "wTW3sjt9vs0" 3) "wt026ux4mz0"Copy the code

3. Latitude and longitude of provincial capitals in China

In order to facilitate you to learn Geospatial, I have sorted out the longitude and latitude of provincial capitals in China. You can help yourself if necessary.

The name of the longitude The dimension
The Beijing municipal 116.405289 39.904987
tianjin 117.190186 39.125595
Hohhot 111.751990 40.841490
yinchuan 106.232480 38.486440
Shijiazhuang city 114.502464 38.045475
jinan 117.000923 36.675808
Zhengzhou city 113.665413 34.757977
Xi ‘an 108.948021 34.263161
Wuhan city 114.298569 30.584354
nanjing 118.76741 32.041546
hefei 117.283043 31.861191
Shanghai 121.472641 31.231707
Changsha city 112.982277 28.19409
nanchang 115.892151 28.676493
hangzhou 120.15358 30.287458
fuzhou 119.306236 26.075302
guangzhou 113.28064 23.125177
Taipei city 121.5200760 25.0307240
Haikou city 110.199890 20.044220
Nanning city 108.320007 22.82402
chongqing 106.504959 29.533155
kunming 102.71225 25.040609
Guiyang city 106.713478 26.578342
chengdu 104.065735 30.659462
Lanzhou city 103.834170 36.061380
xining 101.777820 36.617290
Lhasa 91.11450 29.644150
Urumqi 87.616880 43.826630
shenyang 123.429092 41.796768
Changchun city 125.324501 43.886841
Harbin. 126.642464 45.756966
Hong Kong 114.165460 22.275340
Macau 113.549130 22.198750