I have two keys(geo zset) in redis first "DRIVERS" second "ORDERS" and members inside them. Is it possible to calculate distance between member in DRIVERS and member inside ORDERS? Manual https://redis.io/commands/geodist says that it is only possible between members in one key.
There's no built-in way to do that. However, You can try the following two solutions.
- Use
GEOPOS
command to get locations (longitude and latitude) of the driver and order. Then you can calculate the distance between them by yourself. Or you can put the results into a newGEOSET
and let Redis do the calculation. - Save both drivers and orders in the same
GEOSET
, e.g.GEOADD geo long1 lat1 driver:id
,GEOADD geo long2 lat2 Order:id
GEODIST will only perform distance calculations between geospatial objects within the same Key. However, the backing store for Geospatial objects is a Sorted Set. Using ZUNIONSTORE the two sets can be combined, and the GEODIST can be performed on the resulting set.
> ZUNIONSTORE result 2 DRIVERS ORDERS aggregate min
> GEODIST result "driver_1" "order_1" km
Note: The aggregate min option is required, otherwise any elements that appear in more than one Set will have their scores aggregated. In the case of Geospatial data, this would cause the point to move its Longtitude and Latitude position.
Since GEOSETS are sorted sets you could create a temp key by doing ZUNIONSTORE and then perform operations on those keys
Yes, Redis only provides support for operating between members of same key.
However, there is a workaround you can adopt. This leverages the fact that geospatial
objects are stored using sorted sets
under-the-hood by Redis.
Approach :
The
ZUNIONSTORE
command will create the union of elements in the provided Sorted Sets.By default
ZUNIONSTORE
will sum up the scores for each element, which would cause the Geohash which is used as score for the sorted-set, to change and therefore the point to move.
In order to preserve the Geohash for the point and its correct longitude and latitude, the aggregate MAX
or aggregate MIN
needs to be provided.
Example :
Lets compare the values each ZUNIONSTORE
creates, by looking at what happens to the Geospatial object "Ajinomoto Stadium" which is present in both sets, which has the following Geohash.
> geohash geo:events:"Modern pentathlon" "Ajinomoto Stadium"
1) "xn74zh2x6m0"
Correct way :
> zunionstore foo 2 geo:events:"Modern pentathlon" geo:events:"Football" aggregate min
> geohash foo "Ajinomoto Stadium"
1) "xn74zh2x6m0"
You can see the Geohash has been preserved. Removing the AGGREGATE
option, we now see the following:
> zunionstore foo 2 geo:events:"Modern pentathlon" geo:events:"Football"
> geohash foo "Ajinomoto Stadium"
1) "0zzxzs9jq00"
Hope, you now understand how and why part of the workaround.
© 2022 - 2024 — McMap. All rights reserved.