Skip to content

Commit

Permalink
Python: adds GEOSEARCHSTORE command
Browse files Browse the repository at this point in the history
  • Loading branch information
shohamazon committed Jun 16, 2024
1 parent 4ef40e1 commit 5f0c379
Show file tree
Hide file tree
Showing 8 changed files with 444 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Python: Added OBJECT FREQ command ([#1472](https://github.com/aws/glide-for-redis/pull/1472))
* Python: Added OBJECT IDLETIME command ([#1474](https://github.com/aws/glide-for-redis/pull/1474))
* Python: Added GEOSEARCH command ([#1482](https://github.com/aws/glide-for-redis/pull/1482))
* Python: Added GEOSEARCHSTORE command ([#1581](https://github.com/aws/glide-for-redis/pull/1581))
* Node: Added RENAMENX command ([#1483](https://github.com/aws/glide-for-redis/pull/1483))
* Python: Added OBJECT REFCOUNT command ([#1485](https://github.com/aws/glide-for-redis/pull/1485))
* Python: Added RENAMENX command ([#1492](https://github.com/aws/glide-for-redis/pull/1492))
Expand Down
1 change: 1 addition & 0 deletions glide-core/src/protobuf/redis_request.proto
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ enum RequestType {
LPos = 180;
LCS = 181;
GeoSearch = 182;
GeoSearchStore = 183;
}

message Command {
Expand Down
3 changes: 3 additions & 0 deletions glide-core/src/request_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ pub enum RequestType {
LPos = 180,
LCS = 181,
GeoSearch = 182,
GeoSearchStore = 183,
}

fn get_two_word_command(first: &str, second: &str) -> Cmd {
Expand Down Expand Up @@ -381,6 +382,7 @@ impl From<::protobuf::EnumOrUnknown<ProtobufRequestType>> for RequestType {
ProtobufRequestType::LPos => RequestType::LPos,
ProtobufRequestType::LCS => RequestType::LCS,
ProtobufRequestType::GeoSearch => RequestType::GeoSearch,
ProtobufRequestType::GeoSearchStore => RequestType::GeoSearchStore,
}
}
}
Expand Down Expand Up @@ -569,6 +571,7 @@ impl RequestType {
RequestType::LPos => Some(cmd("LPOS")),
RequestType::LCS => Some(cmd("LCS")),
RequestType::GeoSearch => Some(cmd("GEOSEARCH")),
RequestType::GeoSearchStore => Some(cmd("GEOSEARCHSTORE")),
}
}
}
66 changes: 65 additions & 1 deletion python/python/glide/async_commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2684,7 +2684,7 @@ async def geosearch(
Since: Redis version 6.2.0.
"""
args = _create_geosearch_args(
key,
[key],
search_from,
seach_by,
order_by,
Expand All @@ -2699,6 +2699,70 @@ async def geosearch(
await self._execute_command(RequestType.GeoSearch, args),
)

async def geosearchstore(
self,
destination: str,
source: str,
search_from: Union[str, GeospatialData],
search_by: Union[GeoSearchByRadius, GeoSearchByBox],
count: Optional[GeoSearchCount] = None,
store_dist: bool = False,
) -> int:
"""
Stores the results of a geospatial search into a destination sorted set.
See https://valkey.io/commands/geosearchstore/ for more details.
Note:
When in cluster mode, both `source` and `destination` must map to the same hash slot.
Args:
destination (str): TThe key to store the search results.
source (str): The key of the sorted set representing geospatial data to search from.
search_from (Union[str, GeospatialData]): The location to search from. Can be specified either as a member
from the sorted set or as a geospatial data (see `GeospatialData`).
search_by (Union[GeoSearchByRadius, GeoSearchByBox]): The search criteria.
For circular area search, see `GeoSearchByRadius`.
For rectangular area search, see `GeoSearchByBox`.
count (Optional[GeoSearchCount]): Specifies the maximum number of results to store. See `GeoSearchCount`.
If not specified, stores all results.
store_dist (bool): Whether to store the distance from the center as the sorted set score. Defaults to False.
- The distance is from the center of the circle or box, as a floating-point number, in the same unit specified for that shape.
- If set to False, the geohash of the location will be stored as the sorted set score.
Returns:
int: The number of elements in the resulting sorted set.
Examples:
>>> await client.geoadd("my_geo_sorted_set", {"Palermo": GeospatialData(13.361389, 38.115556), "Catania": GeospatialData(15.087269, 37.502669)})
>>> await client.geosearchstore("my_dest_sorted_set", "my_geo_sorted_set", "Catania", GeoSearchByRadius(175, GeoUnit.MILES))
2 # Number of elements stored in "my_dest_sorted_set".
>>> await client.zrange_withscores("my_dest_sorted_set", RangeByIndex(0, -1))
{"Palermo": 3479099956230698.0, "Catania": 3479447370796909.0} # The elements within te search area, with their geohash as score.
>>> await client.geosearchstore("my_dest_sorted_set", "my_geo_sorted_set", GeospatialData(15, 37), GeoSearchByBox(400, 400, GeoUnit.KILOMETERS), store_dist=True)
2 # Number of elements stored in "my_dest_sorted_set", with distance as score.
>>> await client.zrange_withscores("my_dest_sorted_set", RangeByIndex(0, -1))
{"Catania": 56.4412578701582, "Palermo": 190.44242984775784} # The elements within te search area, with the distance as score.
Since: Redis version 6.2.0.
"""
args = _create_geosearch_args(
[destination, source],
search_from,
search_by,
None,
count,
False,
False,
False,
store_dist,
)

return cast(
int,
await self._execute_command(RequestType.GeoSearchStore, args),
)

async def zadd(
self,
key: str,
Expand Down
8 changes: 6 additions & 2 deletions python/python/glide/async_commands/sorted_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,16 +356,17 @@ def _create_zinter_zunion_cmd_args(


def _create_geosearch_args(
key: str,
keys: List[str],
search_from: Union[str, GeospatialData],
seach_by: Union[GeoSearchByRadius, GeoSearchByBox],
order_by: Optional[OrderBy] = None,
count: Optional[GeoSearchCount] = None,
with_coord: bool = False,
with_dist: bool = False,
with_hash: bool = False,
store_dist: bool = False,
) -> List[str]:
args = [key]
args = [*keys]
if isinstance(search_from, str):
args += ["FROMMEMBER", search_from]
else:
Expand All @@ -389,4 +390,7 @@ def _create_geosearch_args(
if with_hash:
args.append("WITHHASH")

if store_dist:
args.append("STOREDIST")

return args
49 changes: 48 additions & 1 deletion python/python/glide/async_commands/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -1856,7 +1856,7 @@ def geosearch(
Since: Redis version 6.2.0.
"""
args = _create_geosearch_args(
key,
[key],
search_from,
seach_by,
order_by,
Expand All @@ -1868,6 +1868,53 @@ def geosearch(

return self.append_command(RequestType.GeoSearch, args)

def geosearchstore(
self: TTransaction,
destination: str,
source: str,
search_from: Union[str, GeospatialData],
search_by: Union[GeoSearchByRadius, GeoSearchByBox],
count: Optional[GeoSearchCount] = None,
store_dist: bool = False,
) -> TTransaction:
"""
Stores the results of a geospatial search into a destination sorted set.
See https://valkey.io/commands/geosearchstore/ for more details.
Args:
destination (str): TThe key to store the search results.
source (str): The key of the sorted set representing geospatial data to search from.
search_from (Union[str, GeospatialData]): The location to search from. Can be specified either as a member
from the sorted set or as a geospatial data (see `GeospatialData`).
search_by (Union[GeoSearchByRadius, GeoSearchByBox]): The search criteria.
For circular area search, see `GeoSearchByRadius`.
For rectangular area search, see `GeoSearchByBox`.
count (Optional[GeoSearchCount]): Specifies the maximum number of results to store. See `GeoSearchCount`.
If not specified, stores all results.
store_dist (bool): Whether to store the distance from the center as the sorted set score. Defaults to False.
- The distance is from the center of the circle or box, as a floating-point number, in the same unit specified for that shape.
- If set to False, the geohash of the location will be stored as the sorted set score.
Commands response:
int: The number of elements in the resulting sorted set.
Since: Redis version 6.2.0.
"""
args = _create_geosearch_args(
[destination, source],
search_from,
search_by,
None,
count,
False,
False,
False,
store_dist,
)

return self.append_command(RequestType.GeoSearchStore, args)

def zadd(
self: TTransaction,
key: str,
Expand Down
Loading

0 comments on commit 5f0c379

Please sign in to comment.