Search code examples
javaredisjedisspring-data-rediskey-value-store

In Redis, how to query hash data based on the value


I am working on Redis using Spring Data Redis(SDR). I want to query my hash data based on the value(not field name).

This is my hash data -

    Address address1 = Address.builder()
            .city("New York")
            .country("USA")
            .build();
    
    Address address2 = Address.builder()
            .city("New Jersy")
            .country("USA")
            .build();
    
    Address address3 = Address.builder()
            .city("Ohio")
            .country("USA")
            .build();

    Set<Address> addresses = Sets.newHashSet(address1, address2, address3);
    
    Person person = Person.builder()
            .firstname("John")
            .lastname("Leo")
            .address(addresses)
            .build();

    redisTemplate.opsForHash().putAll("employee", jacksonMapper.toHash(person));

Now we have APIs to query by map key, field name like below

Map<String, Object> entries = redisTemplate.opsForHash().entries("employee"); //query by map  key

Object object = redisTemplate.opsForHash().get("employee", "address[0].city"); //query by field name

But I want to query by field value like -

Find all cities starting with 'N'

Find all countries matching the pattern 'U*'

Any help in this regard is appreciated.


Solution

  • There is no Redis command to scan by values on a hash. HSCAN scans the field-names, not the values.

    HSCAN does return the field and the value, so you could use it to return all the cities or countries, using a pattern like "address[*].city", and then do the filtering locally.

    HSCAN is opsForHash().scan(H key, ScanOptions options).

    If filtering locally is not acceptable, you can:

    • Use a Lua script to filter the values Redis-server-side.
    • Create a secondary structure, a Redis set (sets store unique values), like employee:cities where you store (again) these queryable values with SSCAN.
    • Install the RediSearch module on your Redis and move your data to use this, as documents.
    • Create your own Redis module.