Cuando las plataformas de comercio electrónico necesitan asociar la ubicación de un consumidor con el área de entrega de una tienda, las consultas a bases de datos basadas en disco como MySQL o PostGIS pueden convertirse en un cuello de botella a gran escala. TairGIS, una estructura de datos geoespaciales en Tair (Enterprise Edition), utiliza índices R-tree para ejecutar consultas CONTAINS, WITHIN e INTERSECTS en milisegundos. Esto lo hace ideal para escenarios de compra en línea con recogida en tienda (BOPIS) y entregas dentro de la misma ciudad, donde la baja latencia es crítica.
Esta guía muestra cómo usar TairGIS para crear un servicio de búsqueda de tiendas: dadas las coordenadas de un consumidor, se identifican las tiendas que incluyen dicha ubicación dentro de su área de servicio.
Ventajas de TairGIS frente a MySQL o PostGIS
|
Factor |
MySQL / PostGIS |
TairGIS |
|
Almacenamiento |
Basado en disco |
En memoria |
|
Latencia de consulta |
Lenta con grandes volúmenes de datos |
Milisegundos |
|
Tipo de índice |
B-tree / GiST |
R-tree |
|
Operaciones espaciales |
API GIS completa |
CONTAINS, WITHIN, INTERSECTS |
Funcionamiento
Cada tienda en una plataforma de comercio electrónico define un área de servicio, que corresponde a la zona geográfica donde acepta pedidos. Esta área puede ser un distrito específico, una zona con forma irregular o una esfera con un radio determinado alrededor de la tienda.
Cuando un consumidor realiza un pedido, el sistema comprueba si su ubicación se encuentra dentro del área de servicio de alguna tienda. TairGIS gestiona esto mediante dos operaciones:
Agregar los alcances disponibles de las tiendas de una marca a TairGIS.
Consultar las tiendas disponibles cercanas al consumidor según su ubicación.
Requisitos previos
Antes de empezar, asegúrese de contar con lo siguiente:
Una instancia de Tair (Enterprise Edition) con TairGIS habilitado
Python 3.8
El SDK Tair-py instalado: ejecute
pip3 install tair
Conexión a una instancia de Tair
Cree una conexión a su instancia de Tair. Reemplace los valores de marcador de posición con su endpoint y contraseña reales.
# -*- 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
Adición de áreas de servicio de tiendas
Utilice GIS.ADD para almacenar el área de servicio de cada tienda como una geometría POLYGON en formato Well-Known Text (WKT). Agrupe las tiendas por ID de marca para poder consultar todas las tiendas de una marca determinada en una sola llamada.
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
Consulta de tiendas disponibles por ubicación del consumidor
Use gis_contains para identificar qué tiendas incluyen la ubicación del consumidor dentro de su área de servicio. Pase las coordenadas del consumidor como una geometría POINT en formato WKT.
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
(Opcional) Consulta de todas las áreas de servicio de una marca
Utilice GIS.GETALL para recuperar las áreas de servicio de todas las tiendas de una marca específica. Esta función resulta útil para depuración o para generar una vista de mapa de tiendas.
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
Ejemplo
A continuación se muestra un ejemplo que agrega dos tiendas para brand1, recupera todas las áreas de servicio y luego identifica qué tienda atiende a un consumidor ubicado en las coordenadas (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)'))
Salida esperada:
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))']]
La tienda disponible para el consumidor ubicado en las coordenadas (120.19707, 30.19539) es store_2.
Pasos siguientes
Implement digital fences by using TairGIS — uso de TairGIS para supervisar si una entidad rastreada entra o sale de un límite geográfico definido
Referencia de comandos de TairGIS — referencia completa de GIS.ADD, GIS.GETALL, GIS.CONTAINS y otros comandos de TairGIS