node_redis 获取 zrange withscores

Posted

技术标签:

【中文标题】node_redis 获取 zrange withscores【英文标题】:node_redis get zrange withscores 【发布时间】:2014-08-01 04:45:31 【问题描述】:

有人知道我如何通过节点 redis 获取具有分数的成员吗? 我尝试过这样的事情:

client.ZRANGE(key, 0, -1, withscores, function(err, replies) 

);

谢谢。

【问题讨论】:

【参考方案1】:

这段代码看起来不错。查看以下链接以检索您想要的内容:

http://ricochen.wordpress.com/2012/02/28/example-sorted-set-functions-with-node-js-redis/

在此处添加了该链接示例中的代码,以防万一它被删除。

var rc=require('redis').createClient();
var _=require('underscore');

rc.zincrby('myset', 1, 'usera');
rc.zincrby('myset', 5, 'userb');
rc.zincrby('myset', 3, 'userc');
rc.zrevrange('myset', 0, -1, 'withscores', function(err, members) 
        // the resulting members would be something like
        // ['userb', '5', 'userc', '3', 'usera', '1']
        // use the following trick to convert to
        // [ [ 'userb', '5' ], [ 'userc', '3' ], [ 'usera', '1' ] ]
        // learned the trick from
        // http://***.com/questions/8566667/split-javascript-array-in-chunks-using-underscore-js
    var lists=_.groupBy(members, function(a,b) 
        return Math.floor(b/2);
    );
    console.log( _.toArray(lists) );
);
rc.quit();

【讨论】:

【参考方案2】:

看来您的代码是正确的。下面是获取zrange的语法。

没有分数:

redisClient.zrange(keyName,start,stop,function(err,result)
   //result is array
   // every index will give you member name
)

例如:

redisClient.zrange("mySortedset",-1,-1,function(err,result)
       //result is array
       // every index will give you member name
)

有分数:

redisClient.zrange(keyName,start,stop,'withscores',function(err,result)
   //result is array
   // here even index will hold member
   // odd index will hold its score
)

例如:

redisClient.zrange("mySortedset",-1,-1,'withscores',function(err,result)
   //result is array
   // here even index will hold member
   // odd index will hold its score
)

【讨论】:

【参考方案3】:

我尝试了之前接受的答案,但我无法得到我想要的结果,后来我尝试了以下代码并得到了适当的结果,

原始输出:

[ 'player:522',
    '19685',
    'player:164',
    '19594',
    'player:807',
    '19171',
    'player:694',
    '19165',
    'player:905',
    '19108',
    'player:859',
    '19087',
    'player:432',
    '18973',
    'player:515',
    '18831',
    'player:163',
    '18750',
    'player:4',
    '18552' ]

预期输出:


    "player:522": "19685",
    "player:164": "19594",
    "player:807": "19171",
    "player:694": "19165",
    "player:905": "19108",
    "player:859": "19087",
    "player:432": "18973",
    "player:515": "18831",
    "player:163": "18750",
    "player:4": "18552"

解决方案:

redisClient.ZREVRANGE('daily', 1, 10, 'WITHSCORES', function(err, result) 
     result = _.fromPairs(_.chunk(result, 2));
     return res.status(200).json(result);
);

【讨论】:

【参考方案4】:

原版JS解决方案

Redis 调用:

redisClient.zrange(keyName, start, stop, 'withscores', function(err, result) 
  // result.reduce ... (See below)

这是我很快想到的 Vanilla-JS 解决方案。

就我个人而言,导入 underscore 或任何其他库来执行如此简单的任务是没有意义的:

result.reduce(function (a, c, i) 
  var idx = i / 2 | 0;
  if (i % 2) 
    a[idx].score = c;
   else 
    a[idx] =  id: c ;
  

  return a;
, []);

假设这个输入:

['player1', 13, 'player2', 11, 'player4', 7, 'player3', 3, 'player5', 0]

这个函数产生:

[
   id: 'player1', score: 13 ,
   id: 'player2', score: 11 ,
   id: 'player4', score: 7 ,
   id: 'player3', score: 3 ,
   id: 'player5', score: 0 
]

这里还有一个将结果转换成二维数组的方法:

result.reduce(function (a, c, i) 
    var idx = i / 2 | 0;
    if (i % 2) 
        a[idx].push(c);
     else 
        a[idx] = [c];
    
    return a;
, []);

产生以下数组:

[
  [ 'player1', 13 ],
  [ 'player2', 11 ],
  [ 'player4', 7 ],
  [ 'player3', 3 ],
  [ 'player5', 0 ]
]

单行 lambda 版本:

result.reduce((a, c, i) => i % 2 ? (a[i / 2 | 0].data = c, a) : (a[i / 2 | 0] =  id: c , a), []);

【讨论】:

【参考方案5】:

^2.0 版本的正确方法,

var args = [ key,to, from ];

redisClient.zrevrangebyscore(args,function(err,data)

【讨论】:

【参考方案6】:

Vanilla JS reduce 在这里效果很好。

const result = [
    'player:522',
    '19685',
    'player:164',
    '19594',
    'player:807',
    '19171',
    'player:694',
    '19165',
    'player:905',
    '19108',
    'player:859',
    '19087',
    'player:432',
    '18973',
    'player:515',
    '18831',
    'player:163',
    '18750',
    'player:4',
    '18552'
]

const map = result.reduce((map, k, i, res) => 
    if (i % 2 !== 0) 
        map[res[i - 1]] = Number(k);
    
    return map;
, )

地图现在是:


  'player:522': 19685,
  'player:164': 19594,
  'player:807': 19171,
  'player:694': 19165,
  'player:905': 19108,
  'player:859': 19087,
  'player:432': 18973,
  'player:515': 18831,
  'player:163': 18750.65468,
  'player:4': 18552

【讨论】:

【参考方案7】:
var data = []
results.map((result, index) => 
    if (index % 2 == 0) 
        data.push(results[index] =  player: results[index], score: results[index+1] )
    
)

console.log(data)

【讨论】:

以上是关于node_redis 获取 zrange withscores的主要内容,如果未能解决你的问题,请参考以下文章

使用node_redis进行redis数据库crud操作

Redis:zset/zadd/zrange/zrembyscore 命令源码解析

Redis 基础 -- Redis数据类型之sorted_setredis索引和操作元素说明redis time命令

如何在Nodejs中使用缓存

如何在不同端口上的单个服务器上运行 redis?

通过在 C++ 中实现类似“map”函数的 python 问题:调用类成员函数