Redis:如何通过命名空间/规则一次保存(和读取)键值对?

时间:2014-09-20 16:02:18

标签: node.js redis storage database nosql

我想利用Redis来保存和阅读用户的动态列表 从本质上讲,Redis是键值对存储。如何一次阅读所有已保存的用户? (例如,创建名称空间“users / user_id”)

因为我是Redis的初学者,所以 您是否认为在上述情况下使用Redis是正确/有效的?

感谢。

1 个答案:

答案 0 :(得分:0)

使用键/值存储对象时,应通过组合域名和唯一ID来创建域特定键。例如,用户对象可能如下所示:

// typical user data model
var User = function(params) {
    if (!params) params = {};

    this.id = params.id;
    this.username = params.username;
    this.email = params.email;
    // other stuff...
};

然后可以像这样创建域密钥:

var createUserDomainKey = function(id) {
    return 'User:' + id;
};

如果id为'e9f6671440e111e49f14-77817cb77f36',那么关键是:

User:e9f6671440e111e49f14-77817cb77f36

由于redis将存储字符串值,因此您需要序列化,可能使用json进行序列化以保存用户对象。假设一个有效的使用对象会做这样的事情:

var client = redis.createClient(),
    key = createUserDomainKey( user.id ),
    json = JSON.stringify( user ) ;

client.set( key, json, function(err, result) {
    if (err) throw err; // do something here...

    // result is 'OK'
});

对于返回所有用户的简单fire-hose查询,您可以执行以下操作:

var client = redis.createClient();
client.keys( createUserDomainKey( '*' ), function(err, keys) {
    if (err) throw err; // do something here

    // keys contains all the keys matching 'User:*'
});

请注意,redis人员不鼓励使用“密钥”进行生产,因此更好的方法是使用sorted-set构建自己的索引,但如果您的用户列表限制为几百,则没有问题。

由于它返回一个键列表,你需要循环并让每个用户然后解析json字符串以恢复真实对象。假设一个填充的密钥列表,你可以这样做:

var client = redis.getClient(),
    users = [];

var loopCallback = function(err, value) {
    if (!err && value) {
        // parse and add the user model to the list
        users.push( JSON.parse( value ) );
    }

    // pull the next key, if available
    var key = keys.pop();

    if (key) {
        client.get( key, loopCallback );
    } else {
        // list is complete so return users, probably through a callback;
    }
}

// start the loop
loopCallback();

这是一个很好的通用解决方案,但是还有其他一些使用排序集,当您希望通过每次访问访问整个列表时,这些集合可以高效移动。此解决方案使您能够在知道ID时获取单个用户对象。

我希望这会有所帮助。

ps:可以在this project.

的AbstractBaseDao模块中找到对此进行单元测试的完整实现