Search code examples
javacachingredisspring-data-redis

Redis Cache Query using multiple criteria


I have price data from ecommerce like follwoing. Each row is considered as an Domain object lets say PriceInfo

+-----------+----------+-------+------------------+
| ProductId | Provider | Price |       Time       |
+-----------+----------+-------+------------------+
| iphone    | Amazon   |   200 | 13-12-2021 12:50 |
| iphone    | Ebay     |   201 | 13-12-2021 12:50 |
| iphone    | Alibaba  |   202 | 13-12-2021 12:50 |
| GalaxyX2  | Ebay     |   195 | 13-12-2021 12:50 |
| GalaxyX2  | Alibaba  |   196 | 13-12-2021 12:50 |
+-----------+----------+-------+------------------+

Clients are interested in getting all prices from a particular vendor or prices for a single product from various vendors

1.Get price from Ebay

+-----------+----------+-------+------------------+
| ProductId | Provider | Price |       Time       |
+-----------+----------+-------+------------------+
| iphone    | Ebay     |   201 | 13-12-2021 12:50 |
| GalaxyX2  | Ebay     |   195 | 13-12-2021 12:50 |
+-----------+----------+-------+------------------+

2.Get price for iphone

+-----------+----------+-------+------------------+
| ProductId | Provider | Price |       Time       |
+-----------+----------+-------+------------------+
| iphone    | Amazon   |   200 | 13-12-2021 12:50 |
| iphone    | Ebay     |   201 | 13-12-2021 12:50 |
| iphone    | Alibaba  |   202 | 13-12-2021 12:50 |
+-----------+----------+-------+------------------+

How can I define my Redis cache key and how to query the DB to get the above 2 results ?

While saving the pojo I am doing following using Jedis library in java spring boot project:

    public void save(PricingInfo pricingInfo ) {
        template.opsForHash().put(HASH_KEY, pricingInfo.getProductId(), pricingInfo );
    }

Solution

  • You can use RedisReposiroty to get these data, in Redis repository you can define a collection as

    @RedisHash("productPrice")
    public class ProductPrice implements Serializable {
        @Id private String id; // assign id as productId#provider
        @Indexed
        private String productId;
        @Indexed
        private String provider;
        private Double price;
        private Long timestamp;
    }
    

    We've added two indexes in this, one for productId and another one for provider.

    Define a Redis repository with two methods as

    @Repository
    public interface ProductPriceRepository extends CrudRepository<ProductPrice, String>  {
        List<ProductPrice> findByProductId(String productId);
        List<ProductPrice> findByProvider(String provider);
    } 
    

    Now you can autowired ProductPriceRepository in the service.

    To save a record you need to call repository.save method.