How to Implement Conditional Queries and Pagination in Redis Using ZSet and Hash
This guide explains how to achieve pagination and multi‑condition fuzzy queries in Redis by leveraging ZSet for ordered paging and Hash with HSCAN for pattern matching, detailing command usage, combination strategies, and performance optimizations such as temporary set expiration and data freshness handling.
Introduction
Redis is an efficient in‑memory database that supports data types such as String, List, Set, SortedSet, and Hash. Because Redis lacks fuzzy conditional queries and built‑in pagination, scenarios like comments, timelines, or search require custom solutions. This article proposes a technique that combines conditional queries with pagination.
Redis Pagination Using ZSet
Pagination can be implemented with Redis Sorted Set (ZSet), which stores ordered collections. The following commands are essential:
ZADD ZADD key score member [[score,member]…] – adds a member with a score used for sorting.
ZREVRANGE ZREVRANGE key start stop – returns members in a specified range, enabling page retrieval.
ZREM ZREM key member – removes a member, useful for deleting comments.
Sorted Set is well‑suited for pagination because it maintains order and allows range queries. The diagram below illustrates pagination after inserting new records.
Although List can also be paged, it lacks automatic sorting; ZSet is generally preferred unless duplicate entries require List.
Multi‑Condition Fuzzy Query Using Hash
Redis does not provide SQL‑like conditional queries, so we store searchable fields as hash keys and the full record as a JSON value. The HSCAN command iterates over hash fields with pattern matching.
Typical field naming: <id>:<name>:<gender>, with the value being a JSON string of user details.
Examples:
Query all female users – illustrated below.
Query users whose name starts with the character “阿”.
While HSCAN provides pattern matching, it requires scanning all keys, which can be inefficient.
Combining Pagination and Fuzzy Query
When both pagination and dynamic filtering are needed, two options exist:
Perform conditional queries in a persistent database, then cache the result set in Redis for paging.
Implement both conditional fuzzy query and pagination directly in Redis.
The article focuses on the second approach because data may reside only in the cache for high‑performance scenarios.
Implementation Idea
Store searchable fields in a hash as described, using a wildcard pattern to express the filter, e.g., *:*:male for all males or 100*: *:* for IDs starting with 100. When a query arrives, check whether a ZSet keyed by that pattern already exists:
If it exists, paginate it directly with ZREVRANGE.
If not, run HSCAN to collect matching hash fields, insert them into a new ZSet whose key is the pattern, then paginate.
If no ZSet is found, a temporary set is created for pagination.
Performance Optimizations
Generating many temporary ZSets can strain cache memory. Assign an expiration time to each generated set so that unused sets are automatically removed, and refresh the TTL on hits.
Data freshness is another concern because a set reflects the hash state at creation time. Two strategies are possible:
When inserting a new hash entry, also insert it into all relevant ZSets (requires tracking which sets to update).
Periodically rebuild or update the ZSets; this is simpler but may cause stale pagination results.
Conclusion
The article outlines practical techniques for implementing pagination and multi‑condition fuzzy queries in Redis using ZSet and Hash structures, and suggests simple optimization measures such as expiring temporary sets and handling data freshness.
Architect's Guide
Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
