Backend Development 9 min read

Implementing Geolocation‑Based Fraud Detection with Redis GEO Commands

This article outlines a fraud‑detection use case that leverages Redis GEO commands to compare user order addresses with known malicious locations, discusses technology choices among MySQL, Redis, and Elasticsearch, explains Redis’s Sorted‑Set and GeoHash implementation, and provides Java code examples for GEOADD, GEOPOS, GEODIST, and GEORADIUS.

Zhuanzhuan Tech
Zhuanzhuan Tech
Zhuanzhuan Tech
Implementing Geolocation‑Based Fraud Detection with Redis GEO Commands

In a real‑world scenario, a team discovers that some orders are being hijacked by black‑market intermediaries who direct users to specific rental addresses. The team proposes that if a user's order address matches or is near these suspicious addresses, the order should be flagged as potentially fraudulent.

To determine address similarity, the distance between two geographic points must be calculated. The article evaluates three storage/processing options—MySQL, Redis, and Elasticsearch—highlighting their advantages and drawbacks for large‑scale geospatial queries.

Considering performance, low development overhead, and sufficient geolocation capabilities, Redis is chosen as the primary solution. Redis’s GEO API provides four essential commands:

GEOADD – add longitude/latitude for a member.

GEOPOS – retrieve the coordinates of members.

GEODIST – compute the distance between two members.

GEORADIUS – find members within a radius around a point.

The following Java test demonstrates how to use these commands with a Redis client (Jodis):

@Resource
private Jodis jodis;

@Test
public void testGeo() {
    String key = "gk";
    String member1 = "TianAnMen";
    String member2 = "GuGong";

    // GEOADD
    jodis.geoadd(key, 116.3974723219871521, 39.90882345602657466, member1);
    jodis.geoadd(key, 116.39738649129867554, 39.91357605820034138, member2);

    // GEOPOS
    List
geopos = jodis.geopos(key, member1, member2);
    for (GeoCoordinate geopo : geopos) {
        System.out.println(JSONUtil.toJsonStr(geopo));
    }

    // GEODIST
    Double geodist = jodis.geodist(key, member1, member2);
    System.out.println(geodist);

    // GEORADIUS
    List
georadius = jodis.georadius(key, 116.39738649129867554, 39.91357605820034138, 1000, GeoUnit.KM);
    for (GeoRadiusResponse georadiu : georadius) {
        System.out.println(JSONUtil.toJsonStr(georadiu));
    }
}

Redis implements GEO using a Sorted Set where each member’s score is a 52‑bit integer derived from a GeoHash of its longitude and latitude. GeoHash converts the two‑dimensional coordinates into a one‑dimensional binary string by repeatedly bisecting the longitude (‑180 to 180) and latitude (‑90 to 90) ranges.

During encoding, bits from the longitude are placed in even positions and bits from the latitude in odd positions, producing a combined binary code (e.g., 1110011101). This code is stored as the member’s score, enabling fast range queries.

While increasing the number of bisection steps (higher precision) yields finer spatial granularity, it can also introduce distance‑calculation errors because neighboring one‑dimensional codes are not always spatially adjacent. Therefore, practical implementations query neighboring GeoHash cells in addition to the target cell to improve accuracy.

References: https://cloud.tencent.com/developer/article/1949540 . The author, Feng Chao, is a backend developer at ZhaiZhai Financial Technology.

backendfraud detectionRedisGeoHashGeolocationgeoadd
Zhuanzhuan Tech
Written by

Zhuanzhuan Tech

A platform for Zhuanzhuan R&D and industry peers to learn and exchange technology, regularly sharing frontline experience and cutting‑edge topics. We welcome practical discussions and sharing; contact waterystone with any questions.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.