杰瑞科技汇

Java Redis如何实现模糊查询?

Java Redis 模糊查询指南

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

Java Redis如何实现模糊查询?-图1
(图片来源网络,侵删)

使用 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"结尾的键

性能优化建议

  1. 避免使用 KEYS 命令:在生产环境中始终使用 SCAN 命令
  2. 限制返回结果数量:通过 count 参数控制每次迭代返回的元素数量
  3. 使用更具体的模式:尽量减少匹配的键数量
  4. 考虑使用 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 命令以确保生产环境的性能和稳定性。

Java Redis如何实现模糊查询?-图2
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇