When e-commerce platforms need to match a consumer's location to a store's delivery area, queries against disk-based databases like MySQL or PostGIS can become a bottleneck at scale. TairGIS, a geospatial data structure in Tair (Enterprise Edition), uses R-tree indexes to run CONTAINS, WITHIN, and INTERSECTS queries within milliseconds — making it well-suited for buy-online-pickup-in-store (BOPIS) and same-city delivery scenarios where low latency is critical.
This guide shows how to use TairGIS to build a store-finder service: given a consumer's coordinates, identify which stores have that location inside their service area.
Why TairGIS over MySQL or PostGIS
| Factor | MySQL / PostGIS | TairGIS |
|---|---|---|
| Storage | Disk-based | In-memory |
| Query latency | Slow at large data volumes | Milliseconds |
| Index type | B-tree / GiST | R-tree |
| Spatial operations | Full GIS API | CONTAINS, WITHIN, INTERSECTS |
How it works
Each store on an e-commerce platform defines a service area — the geographic zone within which it accepts orders. A service area can be a specific district, an irregularly shaped area, or a sphere with a given radius around the store.
When a consumer places an order, the system checks whether the consumer's location falls inside any store's service area. TairGIS handles this with two operations:
-
Add the available scopes of stores of a brand to TairGIS.
-
Query available stores that sit near a consumer based on the location of the consumer.
Prerequisites
Before you begin, ensure that you have:
-
A Tair (Enterprise Edition) instance with TairGIS enabled
-
Python 3.8
-
The Tair-py SDK installed: run
pip3 install tair
Connect to a Tair instance
Create a connection to your Tair instance. Replace the placeholder values with your actual endpoint and password.
# -*- coding: utf-8 -*-
from typing import Dict
from tair import Tair
from tair import ResponseError
def get_tair() -> Tair:
"""
Connect to a Tair instance.
- host: the endpoint of your Tair instance
- port: the port number (default: 6379)
- password: the password of the default database account.
To connect with a custom database account, use the username:password format.
"""
tair: Tair = Tair(
host="r-8vb************.redis.zhangbei.rds.aliyuncs.com",
port=6379,
db=0,
password="D******23",
decode_responses=True
)
return tair
Add store service areas
Use GIS.ADD to store the service area of each store as a Well-Known Text (WKT) POLYGON geometry. Group stores by brand ID so you can query all stores for a given brand in one call.
def add_brand_store(brandID: str, mapping: Dict[str, str]) -> bool:
"""
Add service areas for all stores of a brand using GIS.ADD.
- brandID: the brand identifier (used as the TairGIS key)
- mapping: a dict mapping store IDs to their WKT POLYGON geometries
"""
try:
tair = get_tair()
ret = tair.gis_add(brandID, mapping)
return ret == 1
except ResponseError as e:
print(e)
return False
Query available stores by consumer location
Use gis_contains to find which stores have the consumer's location inside their service area. Pass the consumer's coordinates as a WKT POINT geometry.
def get_service_store(brandID: str, user_location: str):
"""
Return stores whose service area contains the consumer's location.
- brandID: the brand identifier
- user_location: the consumer's location as a WKT POINT, e.g. 'POINT(lon lat)'
"""
try:
tair = get_tair()
return tair.gis_contains(brandID, user_location)
except:
return None
(Optional) Query all service areas for a brand
Use GIS.GETALL to retrieve the service areas of all stores for a given brand — useful for debugging or building a store-map view.
def get_brand_all(brandID):
"""
Return all stores and their service areas for a brand using GIS.GETALL.
"""
try:
tair = get_tair()
return tair.gis_getall(brandID)
except:
return None
Example
The following example adds two stores for brand1, retrieves all service areas, and then finds which store serves a consumer at coordinates (120.19707, 30.19539).
if __name__ == "__main__":
tair = get_tair()
# Add service areas for two stores of brand1
add_brand_store(
"brand1",
{
"store_1": "POLYGON ((120.14772 30.19513, 120.15370 30.17838, 120.19385 30.18011, 120.18853 30.20817))",
"store_2": "POLYGON ((120.18986 30.20852, 120.19651 30.17988, 120.22512 30.17978, 120.21667 30.22292))"
},
)
print("Query all the stores of brand1 and their available scopes:")
print(get_brand_all('brand1'))
print("Query the available stores for a consumer who is located at coordinates (120.19707, 30.19539):")
print(get_service_store('brand1', 'POINT(120.19707 30.19539)'))
Expected output:
Query all the stores of brand1 and their available scopes.
['store_1', 'POLYGON((120.14772 30.19513,120.1537 30.17838,120.19385 30.18011,120.18853 30.20817))', 'store_2', 'POLYGON((120.18986 30.20852,120.19651 30.17988,120.22512 30.17978,120.21667 30.22292))']
Query the available stores for a consumer who is located at coordinates (120.19707, 30.19539).
[1, ['store_2', 'POLYGON((120.18986 30.20852,120.19651 30.17988,120.22512 30.17978,120.21667 30.22292))']]
The available store for the consumer who is located at coordinates (120.19707, 30.19539) is store_2.
What's next
-
Implement digital fences by using TairGIS — use TairGIS to monitor whether a tracked entity enters or exits a defined geographic boundary
-
TairGIS command reference — full reference for GIS.ADD, GIS.GETALL, GIS.CONTAINS, and other TairGIS commands