ioredis delete all keys by pattern
Asked Answered
R

4

21

I'm using ioredis with express (nodejs) I know that there is a way to delete keys by pattern like this:

redis-cli KEYS "sample_pattern:*" | xargs redis-cli DEL

However, is there a way to do that using ioredis instead?

Regional answered 13/3, 2016 at 9:17 Comment(0)
O
46

The most straightforward way to delete keys by pattern is using keys command to get the keys matching the pattern and then deleting them one by one, which is similar to the command line example you provided. Here's an example implemented with ioredis:

var Redis = require('ioredis');
var redis = new Redis();
redis.keys('sample_pattern:*').then(function (keys) {
  // Use pipeline instead of sending
  // one command each time to improve the
  // performance.
  var pipeline = redis.pipeline();
  keys.forEach(function (key) {
    pipeline.del(key);
  });
  return pipeline.exec();
});

However when your database has a large set of keys (say a million), keys will block the database for several seconds. In that case, scan is more useful. ioredis has scanStream feature to help you iterate over the database easily:

var Redis = require('ioredis');
var redis = new Redis();
// Create a readable stream (object mode)
var stream = redis.scanStream({
  match: 'sample_pattern:*'
});
stream.on('data', function (keys) {
  // `keys` is an array of strings representing key names
  if (keys.length) {
    var pipeline = redis.pipeline();
    keys.forEach(function (key) {
      pipeline.del(key);
    });
    pipeline.exec();
  }
});
stream.on('end', function () {
  console.log('done');
});

Don't forget to check out the official documentation of scan command for more information: http://redis.io/commands/scan.

Overripe answered 15/3, 2016 at 8:48 Comment(2)
I think using unlink is more efficient than del like for example redis.unlink(keys) and delete the pipeline and the forEach loop.Cryo
With both del and unlink, I believe you can spread keys instead of looping over them. e.g. pipeline.del(...keys) or pipeline.unlink(...keys).Outbreak
W
8

First select your keys by pattern, then remove them by del method.

const keys = await ioredis.keys('PATTERN:*');

await ioredis.del(keys);
Wiggs answered 8/1, 2022 at 7:34 Comment(0)
M
1

try the following commands where you can create multiple clients for each prefix, that support set get and clear:

// myredis.js
const Redis = require('ioredis');
const ConnectRedis = require('connect-redis');
const config = {}; // your ioredis config
const clients = {};

/**
 * @private create redis client
 * @param {string} name client name
 * @param {boolean} isSession is this the application session client or not
 * @return {Redis|*}
 */
const createClient = (name, isSession = false) => {
  let client;
  client = new Redis({...config, "keyPrefix":`${name}:`)});
  client.on('error', msg => console.log("Redis Client[" + name + "]: " + msg));
  client.on('connect', () => console.log("Redis Client[" + name + "]: Connected"));
  if (isSession) {
    const RedisStore = ConnectRedis(isSession);
    client = new RedisStore({client});
  }
  return client;
};

/**
 * Create or get redis client
 * @param {string} name client name
 * @return {Redis|*}
 */
const getClient = name => {
  let client = clients[name];
  if (!client || !client.connected) {
    client = clients[name] = createClient(name);
  }
  return client;
};

/**
 * get keys only related to this client prefix
 * @param name
 */
const getClientKeys = name => getClient(name).keys(`${name}:*`).then(keys => keys.map(key => key.substr(name.length + 1)));

/**
 * clear client
 * @param name
 */
const clearClient = name => getClientKeys(name).then(keys => {
  const client = getClient(name);
  client && keys.forEach(key => client.del(key))
});

module.exports = {getClient, clearClient, getClientKeys};

How to use:

const {getClient, clearClient} = require("./myredis");
// this will get a client with prefix "marvel:" and if it is not exists it will be created 
const client = getClient("marvel");

// set value
client.set("fav", "ironman"); 

// get the value
client.get("fav", (error, value) => console.log(value));

// clear client
clearClient("marvel");
Matthias answered 30/11, 2017 at 2:36 Comment(0)
A
-4

i don't not much about ioredis . But i think keys * and for loop can handle it.

Btw ,i suggest that you should use scan and del instead ~

Armindaarming answered 14/3, 2016 at 11:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.