node_redis get zrange withscores
Asked Answered
M

7

5

Does anybody know how can I get members with scores by node redis? I tried something like this:

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

});

Thanks.

Moorings answered 11/6, 2014 at 8:2 Comment(0)
D
6

This code looks good. Check out the following link for retrieving what you want :

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

Added the code here from that link example in case it is ever removed.

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
        // https://mcmap.net/q/54293/-split-javascript-array-in-chunks-using-lodash
    var lists=_.groupBy(members, function(a,b) {
        return Math.floor(b/2);
    });
    console.log( _.toArray(lists) );
});
rc.quit();
Deciare answered 12/6, 2014 at 7:58 Comment(0)
C
3

Seems your code is right. The following is the syntax to get zrange.

without score:

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

Ex :

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

with score:

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

Ex :

redisClient.zrange("mySortedset",-1,-1,'withscores',function(err,result){
   //result is array
   // here even index will hold member
   // odd index will hold its score
})
Charkha answered 4/8, 2015 at 8:54 Comment(0)
M
2

I tried with the prior accepted answers but i could not get the result i want and later i tried with the following code and got appropriate result,

Original output:

[ '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' ]

Expected output:

{
    "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"
}

Solution:

redisClient.ZREVRANGE('daily', 1, 10, 'WITHSCORES', function(err, result) {
     result = _.fromPairs(_.chunk(result, 2));
     return res.status(200).json(result);
});
Mccue answered 6/9, 2018 at 11:9 Comment(0)
P
1

The right approach for versions ^2.0,

var args = [ key,to, from ];

redisClient.zrevrangebyscore(args,function(err,data){
Paduasoy answered 24/3, 2017 at 10:29 Comment(0)
A
1

Vanilla JS Solution

Redis call:

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

Here is a Vanilla-JS solution that I came up with pretty quickly.

For me, personally, it does not make sense to import underscore or any other library to perform such an easy task:

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;
}, []);

Assuming this input:

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

This function yields:

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

Here is another one to transform the result into a two-dimensional array:

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

which produces the following array:

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

One line lambda version:

result.reduce((a, c, i) => i % 2 ? (a[i / 2 | 0].data = c, a) : (a[i / 2 | 0] = { id: c }, a), []);
Absorbing answered 15/4, 2020 at 11:38 Comment(0)
C
1

Vanilla JS reduce works well here.

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;
}, {})

map is now:

{
  '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
}
Colon answered 27/7, 2020 at 21:25 Comment(0)
A
0
var data = []
results.map((result, index) => {
    if (index % 2 == 0) {
        data.push(results[index] = { player: results[index], score: results[index+1] })
    }
})

console.log(data)
Aquarist answered 25/9, 2020 at 9:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.