-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#1033Migrating GEOADD and GEODIST command (#1185)
Co-authored-by: Yuvraj Gosain <[email protected]> Co-authored-by: Jyotinder Singh <[email protected]>
- Loading branch information
1 parent
c608b5c
commit 80e16f6
Showing
11 changed files
with
717 additions
and
180 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
--- | ||
title: GEOADD | ||
description: The `GEOADD` command in DiceDB is used to add geospatial items (longitude,latitude) to a specified key, storing them as a sorted set. This would allow for efficient querying of geographical data using commands like GEOSEARCH. | ||
--- | ||
|
||
The `GEOADD` command in DiceDB is used to add geospatial items (longitude,latitude) to a specified key, storing them as a sorted set. This would allow for efficient querying of geographical data using commands like GEOSEARCH. | ||
|
||
## Syntax | ||
|
||
```bash | ||
GEOADD key [NX | XX] [CH] longitude latitude member [longitude latitude member ...] | ||
``` | ||
|
||
## Parameters | ||
|
||
| Parameter | Description | Type | Required | | ||
| --------- | --------------------------------------------------------------------------------- | ------ | -------- | | ||
| key | The name of the sorted set where the geospatial data will be stored. | string | Yes | | ||
| NX | Only add new elements; do not update existing ones. | NONE | No | | ||
| XX | Only update existing elements; do not add new ones. | NONE | No | | ||
| longitude | longitude of the location (must be between -180 and 180 degrees). | float | Yes | | ||
| latitude | latitude of the location (must be between -85.05112878 and 85.05112878 degrees). | float | Yes | | ||
| member | A unique identifier for the location. | string | Yes | | ||
|
||
|
||
## Return Values | ||
|
||
| Condition | Return Value | | ||
| ------------------------------------------------------------ | ----------------------------------------------------------- | | ||
| For each new member added. | 1 | | ||
| No new member is added. | 0 | | ||
| Incorrect Argument Count |`ERR wrong number of arguments for 'geoadd' command` | | ||
| If the longitude is not a valid number or is out of range. |`ERR invalid longitude` | | ||
| If the latitude is not a valid number or is out of range. |`ERR invalid latitude` | | ||
|
||
## Behaviour | ||
|
||
When the GEOADD command is issued, DiceDB performs the following steps: | ||
|
||
1. It checks whether longitude and latitude are valid or not. If not an error is thrown. | ||
2. It checks whether the set exists or not. | ||
3. If set doesn't exist new set is created or else the same set is used. | ||
4. It adds or updates the member in the set. | ||
5. It returns number of members added. | ||
|
||
## Errors | ||
|
||
1.`Wrong number of arguments for 'GEOADD' command` | ||
- Error Message: (error) ERR wrong number of arguments for 'geoadd' command. | ||
- Occurs when the command is executed with an incorrect number of arguments. | ||
|
||
2. `Longitude not a valid number or is out of range ` | ||
- Error Message: (error) ERR invalid longitude. | ||
- Occurs when longitude is out of range(-180 to 180) or not a valid number. | ||
|
||
3. `Latitude not a valid number or is out of range ` | ||
- Error Message: (error) ERR invalid latitude. | ||
- Occurs when latitude is out of range(-85.05112878 to 85.05112878) or not a valid number. | ||
|
||
## Example Usage | ||
|
||
Here are a few examples demonstrating the usage of the GEOADD command: | ||
|
||
### Example : Adding new member to a set | ||
|
||
```bash | ||
127.0.0.1:7379> GEOADD locations 13.361389 38.115556 "Palermo" | ||
1 | ||
``` | ||
|
||
### Example : Updating an already existing member to a set | ||
|
||
```bash | ||
127.0.0.1:7379> GEOADD locations 13.361389 39.115556 "Palermo" | ||
0 | ||
``` | ||
|
||
### Example : Error Adding a member with invalid longitude | ||
|
||
```bash | ||
127.0.0.1:7379> GEOADD locations 181.120332 39.115556 "Jamaica" | ||
(error) ERROR invalid longitude | ||
``` | ||
|
||
### Example : Error Adding a member with invalid latitde | ||
|
||
```bash | ||
127.0.0.1:7379> GEOADD locations 13.361389 91.115556 "Venice" | ||
(error) ERROR invalid latitude | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
--- | ||
title: GEODIST | ||
description: The `GEODIST` command in Redis is used to calculate the distance between two members (geospatial points) stored in a geospatial index(set). | ||
--- | ||
|
||
The `GEODIST` command in DiceDB is used to calculate the distance between two members (geospatial points) stored in a geospatial index(set). | ||
|
||
## Syntax | ||
|
||
```bash | ||
GEODIST key member1 member2 [m | km | ft | mi] | ||
``` | ||
|
||
## Parameters | ||
|
||
| Parameter | Description | Type | Required | | ||
| --------- | --------------------------------------------------------------------------------- | ------ | -------- | | ||
| key | The name of the sorted set where the geospatial data is stored. | string | Yes | | ||
| member1 | The name of the member1 from where you want to measure the distance. | string | Yes | | ||
| member2 | The name of the member2 to where you want to measure the distance. | string | Yes | | ||
| m | The distance to be measured in meters. | NONE | NO | | ||
| km | The distance to be measured in kilometers. | NONE | NO | | ||
| ft | The distance to be measured in feet. | NONE | NO | | ||
| mi | The distance to be measured in miles. | NONE | NO | | ||
|
||
|
||
## Return Values | ||
|
||
| Condition | Return Value | | ||
| ------------------------------------------------------------ | ----------------------------------------------------------- | | ||
| If both members exist in the set with no option | distance b/w them in meters | | ||
| If both members exist in the set with option km | distance b/w them in kilometers | | ||
| If both members exist in the set with option ft | distance b/w them in feet | | ||
| If both members exist in the set with option mi | distance b/w them in miles | | ||
| If any member doesn't exist in Set | nil | | ||
| Incorrect Argument Count |`ERR wrong number of arguments for 'geodist' command` | | ||
|
||
## Behaviour | ||
|
||
When the GEODIST command is issued, DiceDB performs the following steps: | ||
|
||
1. It gets the sorted set(key). | ||
2. It gets the scores(geohashes) from the sorted sets for both the members. | ||
3. It calculates the distance bw them and returns it. | ||
|
||
## Errors | ||
|
||
1.`Wrong number of arguments for 'GEODIST' command` | ||
- Error Message: (error) ERR wrong number of arguments for 'geodist' command. | ||
- Occurs when the command is executed with an incorrect number of arguments. | ||
|
||
|
||
## Example Usage | ||
|
||
Here are a few examples demonstrating the usage of the GEODIST command: | ||
|
||
### Example : Adding new member to a set | ||
|
||
```bash | ||
127.0.0.1:7379> GEOADD cities -74.0060 40.7128 "New York" | ||
1 | ||
127.0.0.1:7379> GEOADD cities -79.3470 43.6510 "Toronto" | ||
1 | ||
127.0.0.1:7379> GEODIST cities "New York" "Toronto" | ||
"548064.1868" | ||
127.0.0.1:7379> GEODIST cities "New York" "Toronto km" | ||
"548.0642" | ||
127.0.0.1:7379> GEODIST cities "New York" "Toronto mi" | ||
"340.5521" | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package http | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestGeoAdd(t *testing.T) { | ||
exec := NewHTTPCommandExecutor() | ||
|
||
testCases := []struct { | ||
name string | ||
commands []HTTPCommand | ||
expected []interface{} | ||
}{ | ||
{ | ||
name: "GEOADD with wrong number of arguments", | ||
commands: []HTTPCommand{ | ||
{Command: "GEOADD", Body: map[string]interface{}{"key": "mygeo", "values": []interface{}{"1.2", "2.4"}}}, | ||
}, | ||
expected: []interface{}{"ERR wrong number of arguments for 'geoadd' command"}, | ||
}, | ||
{ | ||
name: "GEOADD Commands with new member and updating it", | ||
commands: []HTTPCommand{ | ||
{Command: "GEOADD", Body: map[string]interface{}{"key": "mygeo", "values": []interface{}{"1.2", "2.4", "NJ"}}}, | ||
{Command: "GEOADD", Body: map[string]interface{}{"key": "mygeo", "values": []interface{}{"1.24", "2.48", "NJ"}}}, | ||
}, | ||
expected: []interface{}{float64(1), float64(0)}, | ||
}, | ||
{ | ||
name: "GEOADD Adding both XX and NX options together", | ||
commands: []HTTPCommand{ | ||
{Command: "GEOADD", Body: map[string]interface{}{"key": "mygeo", "values": []interface{}{"XX", "NX", "1.2", "2.4", "NJ"}}}, | ||
}, | ||
expected: []interface{}{"ERR XX and NX options at the same time are not compatible"}, | ||
}, | ||
{ | ||
name: "GEOADD Invalid Longitude", | ||
commands: []HTTPCommand{ | ||
{Command: "GEOADD", Body: map[string]interface{}{"key": "mygeo", "values": []interface{}{"181", "2.4", "MT"}}}, | ||
}, | ||
expected: []interface{}{"ERR invalid longitude"}, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
for i, cmd := range tc.commands { | ||
result, _ := exec.FireCommand(cmd) | ||
assert.Equal(t, tc.expected[i], result, "Value mismatch for cmd %s", cmd) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestGeoDist(t *testing.T) { | ||
exec := NewHTTPCommandExecutor() | ||
|
||
testCases := []struct { | ||
name string | ||
commands []HTTPCommand | ||
expected []interface{} | ||
}{ | ||
{ | ||
name: "GEODIST b/w existing points", | ||
commands: []HTTPCommand{ | ||
{Command: "GEOADD", Body: map[string]interface{}{"key": "points", "values": []interface{}{"13.361389", "38.115556", "Palermo"}}}, | ||
{Command: "GEOADD", Body: map[string]interface{}{"key": "points", "values": []interface{}{"15.087269", "37.502669", "Catania"}}}, | ||
{Command: "GEODIST", Body: map[string]interface{}{"key": "points", "values": []interface{}{"Palermo", "Catania"}}}, | ||
{Command: "GEODIST", Body: map[string]interface{}{"key": "points", "values": []interface{}{"Palermo", "Catania", "km"}}}, | ||
}, | ||
expected: []interface{}{float64(1), float64(1), float64(166274.144), float64(166.2741)}, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
for i, cmd := range tc.commands { | ||
result, _ := exec.FireCommand(cmd) | ||
assert.Equal(t, tc.expected[i], result, "Value mismatch for cmd %s", cmd) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package resp | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestGeoAdd(t *testing.T) { | ||
conn := getLocalConnection() | ||
defer conn.Close() | ||
|
||
testCases := []struct { | ||
name string | ||
cmds []string | ||
expect []interface{} | ||
}{ | ||
{ | ||
name: "GeoAdd With Wrong Number of Arguments", | ||
cmds: []string{"GEOADD mygeo 1 2"}, | ||
expect: []interface{}{"ERR wrong number of arguments for 'geoadd' command"}, | ||
}, | ||
{ | ||
name: "GeoAdd With Adding New Member And Updating it", | ||
cmds: []string{"GEOADD mygeo 1.21 1.44 NJ", "GEOADD mygeo 1.22 1.54 NJ"}, | ||
expect: []interface{}{int64(1), int64(0)}, | ||
}, | ||
{ | ||
name: "GeoAdd With Adding New Member And Updating it with NX", | ||
cmds: []string{"GEOADD mygeo 1.21 1.44 MD", "GEOADD mygeo 1.22 1.54 MD"}, | ||
expect: []interface{}{int64(1), int64(0)}, | ||
}, | ||
{ | ||
name: "GEOADD with both NX and XX options", | ||
cmds: []string{"GEOADD mygeo NX XX 1.21 1.44 MD"}, | ||
expect: []interface{}{"ERR XX and NX options at the same time are not compatible"}, | ||
}, | ||
{ | ||
name: "GEOADD invalid longitude", | ||
cmds: []string{"GEOADD mygeo 181.0 1.44 MD"}, | ||
expect: []interface{}{"ERR invalid longitude"}, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
for i, cmd := range tc.cmds { | ||
result := FireCommand(conn, cmd) | ||
assert.Equal(t, tc.expect[i], result, "Value mismatch for cmd %s", cmd) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestGeoDist(t *testing.T) { | ||
conn := getLocalConnection() | ||
defer conn.Close() | ||
|
||
testCases := []struct { | ||
name string | ||
cmds []string | ||
expect []interface{} | ||
delays []time.Duration | ||
}{ | ||
{ | ||
name: "GEODIST b/w existing points", | ||
cmds: []string{ | ||
"GEOADD points 13.361389 38.115556 Palermo", | ||
"GEOADD points 15.087269 37.502669 Catania", | ||
"GEODIST points Palermo Catania", | ||
"GEODIST points Palermo Catania km", | ||
}, | ||
expect: []interface{}{int64(1), int64(1), "166274.144", "166.2741"}, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
for i, cmd := range tc.cmds { | ||
result := FireCommand(conn, cmd) | ||
assert.Equal(t, tc.expect[i], result, "Value mismatch for cmd %s", cmd) | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.