Bạn có biết?
Ứng dụng giao đồ ăn: bấm nút là thấy 20 quán ăn quanh mình, sắp xếp theo khoảng cách, kèm tọa độ chính xác. Không cần database spatial phức tạp, không cần gọi Google Maps API — chỉ với vài lệnh Redis Geo, bạn có cả hệ thống tìm kiếm vị trí chạy trong mili giây.
Redis Geo là một tập lệnh xây dựng trên Sorted Sets — tọa độ kinh/vĩ được mã hóa thành geohash, lưu làm score. Nhờ vậy bạn được cả hai thế giới: tìm kiếm không gian (gần tôi) VÀ sắp xếp theo khoảng cách, tất cả O(log N).
Các lệnh Geo cơ bản
| Lệnh | Chức năng |
| --- | --- |
| GEOADD | Thêm địa điểm (kinh độ, vĩ độ, tên) |
| GEOPOS | Lấy tọa độ đã lưu |
| GEODIST | Khoảng cách giữa 2 điểm |
| GEOSEARCH | Tìm trong bán kính hoặc theo hình chữ nhật (Redis 6.2+) |
| GEOSEARCHSTORE | Lưu kết quả tìm kiếm vào key mới |
| GEOHASH | Lấy chuỗi geohash của địa điểm |
# Thêm địa điểm: GEOADD key longitude latitude member
GEOADD restaurants 105.8342 21.0278 "Pho Bat Dan"
GEOADD restaurants 105.8233 21.0305 "Bun Cha Huong Lien"
GEOADD restaurants 105.8535 21.0333 "Banh Mi 25"
# Lấy tọa độ đã lưu
GEOPOS restaurants "Pho Bat Dan"
# 1) 1) "105.83420181274414062" 2) "21.02779956088399727"
# Khoảng cách giữa 2 điểm (m = meters, km = kilometers, mi, ft)
GEODIST restaurants "Pho Bat Dan" "Bun Cha Huong Lien" km
# "1.2147"
# Tìm nhà hàng trong bán kính 2km quanh vị trí hiện tại (21.0285, 105.8300)
GEOSEARCH restaurants FROMLONLAT 105.8300 21.0285 BYRADIUS 2 km ASC
# 1) "Bun Cha Huong Lien"
# 2) "Pho Bat Dan"
# Kèm khoảng cách và tọa độ
GEOSEARCH restaurants FROMLONLAT 105.8300 21.0285 BYRADIUS 2 km ASC WITHDIST WITHCOORD
GEOSEARCH cũng hỗ trợ tìm theo hình chữ nhật (BYBOX) — hữu ích khi hiển thị theo khung bản đồ:
# Tìm trong hình chữ nhật 5km x 3km quanh trung tâm
GEOSEARCH restaurants FROMLONLAT 105.8300 21.0285 BYBOX 5 3 km ASC
Use case thực tế
- Giao đồ ăn / taxi — tìm cửa hàng, tài xế gần nhất trong bán kính
- Mạng xã hội — "người gần tôi", check-in, gợi ý bạn bè quanh khu vực
- Thương mại điện tử — tìm cửa hàng, kho giao hàng gần khách nhất
- Chống gian lận — kiểm tra vị trí đăng nhập bất thường so với lịch sử
- Game — tìm người chơi trong vùng, spawn quái quanh người chơi
Ví dụ Node.js: tìm quán ăn gần tôi
import Redis from "ioredis";
const redis = new Redis();
// Seed dữ liệu nhà hàng
await redis.geoadd("restaurants", 105.8342, 21.0278, "Pho Bat Dan");
await redis.geoadd("restaurants", 105.8233, 21.0305, "Bun Cha Huong Lien");
await redis.geoadd("restaurants", 105.8535, 21.0333, "Banh Mi 25");
// API: tìm quán trong 3km, trả kèm khoảng cách
async function findNearby(lng, lat, radiusKm = 3) {
return redis.geosearch(
"restaurants",
"FROMLONLAT", lng, lat,
"BYRADIUS", radiusKm, "km",
"ASC", "WITHDIST"
);
}
const results = await findNearby(105.8300, 21.0285);
// [ [ 'Bun Cha Huong Lien', '0.9889' ], [ 'Pho Bat Dan', '1.2147' ] ]
Kết hợp với các cấu trúc khác
Geo không hoạt động đơn độc — pattern phổ biến là lưu ID địa điểm trong Geo key, còn chi tiết (tên, giá, rating, ảnh) để trong Hash riêng:
# Geo key chỉ chứa ID
GEOADD restaurants 105.8342 21.0278 1001
# Chi tiết trong Hash
HSET restaurant:1001 name "Pho Bat Dan" price "50000" rating "4.5"
HSET restaurant:1002 name "Bun Cha Huong Lien" price "60000" rating "4.7"
# Tìm ID gần nhất rồi lấy chi tiết
GEOSEARCH restaurants FROMLONLAT 105.8300 21.0285 BYRADIUS 3 km ASC
# 1) "1002" 2) "1001"
HGETALL restaurant:1002
Cách này giúp Geo key nhỏ gọn, dễ cache và dễ cập nhật chi tiết mà không phải thêm lại tọa độ.
- Đặt tên key theo khu vực —
geo:hanoi:restaurants,geo:hcmc:shops… giúp tìm kiếm trong phạm vi nhỏ hơn, nhanh hơn - Lưu ID, không lưu toàn bộ dữ liệu — Geo key chỉ nên chứa ID, chi tiết để Hash/DB
- Kinh độ trước, vĩ độ sau — GEOADD nhận (lng, lat), dễ nhầm thứ tự nhất trong toàn bộ Redis
- Độ chính xác giới hạn — geohash dài ~10 ký tự, sai số vài cm; đủ cho hầu hết use case, không cần chính xác hơn
- GEOSEARCHSTORE cho kết quả lặp lại — nếu nhiều user cùng khu vực, cache kết quả chung để giảm tải
- Lưu ý: Redis Geo dùng kỹ thuật geohash — không phải chỉ số R-tree; phép tìm theo bán kính rất nhanh nhưng không hỗ trợ "polygon tùy ý"
Redis Geo biến bài toán "tìm thứ gì đó quanh tôi" thành vài lệnh đơn giản: GEOADD thêm dữ liệu, GEOSEARCH tìm trong bán kính kèm khoảng cách, GEOSEARCHSTORE cache kết quả. Kết hợp với Hash để lưu chi tiết, bạn có một search engine vị trí cực nhanh mà không cần thêm bất kỳ hạ tầng nào.
0 bình luận
Đang tải bình luận...
Để lại bình luận