skip to Main Content

In Redis cache I have 3 keys

1111-2222-4444
1111-2222-3333
1112-2222-3333

I have a partial key 1111, and I want to return the two keys 1111-2222-4444, 1111-2222-3333

I have the following code

public List<String> getKeys(String partialkey) {
        ScanParams scanParams = new ScanParams();
        scanParams.match("*");
        String cur = redis.clients.jedis.ScanParams.SCAN_POINTER_START;
        Jedis jedis = jedisPool.getResource();

        List<String> keys = new ArrayList<String>();
        boolean cycleIsFinished = false;
        while (!cycleIsFinished) {
            ScanResult<String> scanResult = jedis.scan(cur, scanParams);
            cur = scanResult.getCursor();
            for(String key :scanResult.getResult()) {
                if(isKey(key, partialkey) ) {
                    keys.add(key);
                }
            }
            if (cur.equals("0")) {
                cycleIsFinished = true;
            }
        }
        return keys;
    }

And a method to match for partial key

    private boolean isKey(String key, String match) {
        String[] fields = key.split("-");
        if(match.equals(fields[0])) {
            return true;
        }
        return false;
    }

Now this works, but it seems very clunky, there could be thousands of keys, to search through.
My question is, is there a pure redis way to do this.
Where it only returns the two keys, that the partial key matches to.

3

Answers


  1. Chosen as BEST ANSWER

    With thanks to shmosel

    public List<String> getKeys(String partialkey) {
            ScanParams scanParams = new ScanParams();
            scanParams.match(partialkey+"-*");
            String cur = redis.clients.jedis.ScanParams.SCAN_POINTER_START;
            Jedis jedis = jedisPool.getResource();
    
            List<String> keys = new ArrayList<String>();
            boolean cycleIsFinished = false;
            while (!cycleIsFinished) {
                ScanResult<String> scanResult = jedis.scan(cur, scanParams);
                cur = scanResult.getCursor();
                for(String key :scanResult.getResult()) {
                    //if(isKey(key, partialkey) ) {
                        keys.add(key);
                    //}
                }
                if (cur.equals("0")) {
                    cycleIsFinished = true;
                }
            }
            return keys;
        }
    

  2. Use Redis command KEYS to return all keys matching pattern

    KEYS 1111-*
    

    Redis example

    Java example

    private List<String> getKeys(String partialKey) {
        try (Jedis jedis = jedisPool.getResource()) {
            return jedis.keys(partialKey + "-*")
                    .stream()
                    .toList();
        }
    }
    
    Login or Signup to reply.
  3. Be carefull with jedis.keys() method, it could ruin performance:

    Warning: consider KEYS as a command that should only be used in production environments with extreme care. It may ruin performance when it is executed against large databases. This command is intended for debugging and special operations, such as changing your keyspace layout. Don’t use KEYS in your regular application code. If you’re looking for a way to find keys in a subset of your keyspace, consider using SCAN or sets.

    More explanation here, use SCAN is good alternative

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search