Java Redis 模糊查询指南
在 Java 中使用 Redis 进行模糊查询,主要依赖于 Redis 的 KEYS 命令或 SCAN 命令,以下是几种实现方式:

使用 Jedis 客户端
使用 KEYS 命令(不推荐用于生产环境)
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class RedisKeysExample {
private JedisPool jedisPool;
public RedisKeysExample() {
this.jedisPool = new JedisPool("localhost", 6379);
}
public Set<String> fuzzySearchKeys(String pattern) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.keys(pattern);
}
}
}
注意:KEYS 命令会阻塞 Redis 服务器,在生产环境中不建议使用,特别是在数据量大的时候。
使用 SCAN 命令(推荐)
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
public class RedisScanExample {
private JedisPool jedisPool;
public RedisScanExample() {
this.jedisPool = new JedisPool("localhost", 6379);
}
public Set<String> fuzzySearchKeys(String pattern) {
try (Jedis jedis = jedisPool.getResource()) {
Set<String> keys = new HashSet<>();
ScanParams scanParams = new ScanParams().match(pattern);
String cursor = "0";
do {
ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
keys.addAll(scanResult.getResult());
cursor = scanResult.getCursor();
} while (!cursor.equals("0"));
return keys;
}
}
}
使用 Spring Data Redis
使用 RedisTemplate
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Component;
import java.util.Set;
@Component
public class RedisFuzzySearch {
private final RedisTemplate<String, Object> redisTemplate;
public RedisFuzzySearch(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
public Set<String> fuzzySearchKeys(String pattern) {
return redisTemplate.execute(connection -> {
Set<String> keys = new HashSet<>();
Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().match(pattern).count(1000).build());
while (cursor.hasNext()) {
keys.add(new String(cursor.next()));
}
return keys;
}, true);
}
}
模糊查询模式示例
Redis 支持以下通配符:
- 匹配任意数量的字符
- 匹配单个字符
[]匹配指定范围内的字符
示例模式:
user:*- 匹配所有以"user:"开头的键session:*:*- 匹配所有以"session:"开头且包含两个冒号的键temp:*:2025- 匹配所有以"temp:"开头,以":2025"结尾的键
性能优化建议
- 避免使用 KEYS 命令:在生产环境中始终使用 SCAN 命令
- 限制返回结果数量:通过
count参数控制每次迭代返回的元素数量 - 使用更具体的模式:尽量减少匹配的键数量
- 考虑使用 Hash 结构:如果需要频繁模糊查询,可以考虑将相关数据存储在 Hash 结构中,然后使用 HKEYS 命令
完整示例
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import java.util.HashSet;
import java.util.Set;
public class RedisFuzzySearchExample {
public static void main(String[] args) {
JedisPool jedisPool = new JedisPool("localhost", 6379);
// 添加一些测试数据
try (Jedis jedis = jedisPool.getResource()) {
jedis.set("user:1:name", "Alice");
jedis.set("user:1:email", "alice@example.com");
jedis.set("user:2:name", "Bob");
jedis.set("user:2:email", "bob@example.com");
jedis.set("session:abc123", "data1");
jedis.set("session:def456", "data2");
}
// 创建模糊搜索实例
RedisFuzzySearch searcher = new RedisFuzzySearch(jedisPool);
// 查找所有以"user:"开头的键
Set<String> userKeys = searcher.fuzzySearchKeys("user:*");
System.out.println("User keys: " + userKeys);
// 查找所有包含"session:"的键
Set<String> sessionKeys = searcher.fuzzySearchKeys("*session:*");
System.out.println("Session keys: " + sessionKeys);
jedisPool.close();
}
static class RedisFuzzySearch {
private final JedisPool jedisPool;
public RedisFuzzySearch(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
public Set<String> fuzzySearchKeys(String pattern) {
try (Jedis jedis = jedisPool.getResource()) {
Set<String> keys = new HashSet<>();
ScanParams scanParams = new ScanParams().match(pattern);
String cursor = "0";
do {
ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
keys.addAll(scanResult.getResult());
cursor = scanResult.getCursor();
} while (!cursor.equals("0"));
return keys;
}
}
}
}
代码展示了如何在 Java 中使用 Redis 进行模糊查询,推荐使用 SCAN 命令而不是 KEYS 命令以确保生产环境的性能和稳定性。

