【问题标题】:how to get all keys and values in redis in javascript?如何在javascript中获取redis中的所有键和值?
【发布时间】:2017-08-13 02:40:57
【问题描述】:

我正在使用 javascript 创建一个节点 API。我使用 redis 作为我的键值存储。 我在我的应用程序中创建了一个 redis 客户端,并且能够获取特定键的值。

我想检索所有键及其值。 到目前为止,我已经这样做了:

app.get('/jobs', function (req, res) {
    var jobs = [];
    client.keys('*', function (err, keys) {
        if (err) return console.log(err);
        if(keys){
            for(var i=0;i<keys.length;i++){
                client.get(keys[i], function (error, value) {
                    if (err) return console.log(err);
                    var job = {};
                    job['jobId']=keys[i];
                    job['data']=value;
                    jobs.push(job);
                });  
            }
            console.log(jobs);
            res.json({data:jobs});
        }
    });
});

但我总是得到空白数组作为响应。

有没有办法在javascript中做到这一点?

谢谢

【问题讨论】:

标签: javascript node.js redis key-value


【解决方案1】:

首先,您的问题中的问题是,在for 循环中,client.get 是通过 异步 回调调用的,其中 同步 @987654327 @ 循环不会等待异步回调,因此下一行 res.json({data:jobs}); 在异步回调之前的 for 循环之后立即被调用。在调用res.json({data:jobs}); 行时,数组jobs 仍为空[] 并与响应一起返回。

为了缓解这种情况,您应该使用任何 promise 模块,例如 asyncbluebirdES6 Promise 等。

使用async模块修改代码,

app.get('/jobs', function (req, res) {
    var jobs = [];
    client.keys('*', function (err, keys) {
        if (err) return console.log(err);
        if(keys){
            async.map(keys, function(key, cb) {
               client.get(key, function (error, value) {
                    if (error) return cb(error);
                    var job = {};
                    job['jobId']=key;
                    job['data']=value;
                    cb(null, job);
                }); 
            }, function (error, results) {
               if (error) return console.log(error);
               console.log(results);
               res.json({data:results});
            });
        }
    });
});

但是从Redisdocumentation可以看出, 密钥用于调试和特殊操作,例如 更改您的键空间布局,不建议用于生产 环境。

因此,我建议使用另一个名为redisscan 的模块,如下所示,它使用SCAN 而不是KEYS,如Redis documentation 中所建议的那样。

类似的,

var redisScan = require('redisscan');
var redis     = require('redis').createClient();


redisScan({
        redis: redis,
        each_callback: function (type, key, subkey, value, cb) {
            console.log(type, key, subkey, value);
            cb();
        },
        done_callback: function (err) {
            console.log("-=-=-=-=-=--=-=-=-");
            redis.quit();
        }
    });

【讨论】:

    【解决方案2】:

    2 个请求的组合:

    import * as ioredis from 'ioredis';
    
    const redis = new ioredis({
        port: redisPort,
        host: redisServer,
        password: '',
        db: 0
      });
    
    const keys = await redis.collection.keys('*');
    const values = await redis.collection.mget(keys);
    

    两个数组的顺序相同。

    【讨论】:

    【解决方案3】:

    这将获取所有键但没有值:

    const redis = require('redis');
    const client = redis.createClient();
    
    client.keys('*', (err, keys) => {
      // ...
    });
    

    现在您需要以通常的方式获取这些键的值。例如:

    Promise.all(keys.map(key => client.getAsync(key))).then(values => {
      // ...
    });
    

    或使用async 模块或任何你喜欢的方式。

    【讨论】:

    • 值得一提的是,文档明确指出不应使用此命令来执行此操作
    • @baao 是的。我认为获取所有键和所有值是证明 Redis 在这里以一种奇怪的方式使用的需要。不幸的是,问题是关于解决方案,而不是问题,因此很难推荐其他任何东西。
    • Redis 在这里的使用方式很奇怪 没错。 :D
    • 尽管有问题,但更好的解决方案是使用SCAN 而不是KEYS
    【解决方案4】:

    你不应该这样做。首先,不建议在生产中使用KEYS *。其次,这不能扩展(集群)。

    您可以将缓存条目组织成 SET 并查询 SET 中的项目,然后检索引用键。这也使失效更容易。

    了解一些数据存储最佳做法。

    https://redis.io/topics/data-types-intro how to get all keys and values in redis in javascript?

    【讨论】:

      【解决方案5】:

      您可能会在此链接中找到有用的东西

      https://github.com/NodeRedis/node_redis/tree/master/examples

      【讨论】:

        猜你喜欢
        • 2013-10-21
        • 2017-04-03
        • 2015-08-24
        • 2014-03-10
        • 1970-01-01
        • 1970-01-01
        • 2020-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多