var db = redis.createClient();var s1 = "some string calculated in Node.js elsewhere";var s2 = "some string calculated in Node.js elsewhere";var s3 = "some string calculated in Node.js elsewhere";var rs = "myLua script"db.EVAL(rs, 0, ****3 SET names here***, function(err, replies) {if (err) { console.log (err);return console.error("error response - " + err);}res.json (JSON.parse(replies));});
local c = redis.call('SINTER', unpack(ARGV))
db.EVAL(rs, 0 , 's1', 's2', 's3', function(err, replies) { … => worksdb.EVAL(rs, 0 , "s1", "s2", "s3", function(err, replies) { … => worksdb.EVAL(rs, 0 , s1, s2, s3, function(err, replies) { … => does NOT work, c=[ ]
--
You received this message because you are subscribed to the Google Groups "Redis DB" group.
To unsubscribe from this group and stop receiving emails from it, send an email to redis-db+u...@googlegroups.com.
To post to this group, send email to redi...@googlegroups.com.
Visit this group at http://groups.google.com/group/redis-db.
For more options, visit https://groups.google.com/groups/opt_out.
Sorry, thanks for the pointers, perhaps I wasn't clear.
's1', 's2' and 's3' are in fact the names of 3 sets is Redis. What are 'passed as variables' above within the EVAL statement in fact resolve to string variables 's1', 's2' and 's3'. Easily verified with SMEMBERS to see they are populated and also SINTER s1 s2 s3 does in fact give the right intersection, as I mentioned above. I've checked this with lua script loaded and ran via redis-cli, also sent via a Node.js script. That's not the problem I'm having.
To state slightly more narrowly:
db.EVAL(rs, 0 , 's1', 's2', 's3', function(err, replies) { … => works in every way.
But
myVar1 = 's1';
myVar2 = 's2';
myVar3 = 's3';
db.EVAL(rs, 0 , myVar1, myVar2, myVar3, function(err, replies) { … => does NOT work
db.EVAL(rs, 3 , myVar1, myVar2, myVar3, function(err, replies) { … => does NOT work either
db.EVAL(rs, 0 , myVar1, myVar2, myVar3, function(err, replies) { …
local c = redis.call('SINTER', unpack(ARGV)) which should unpack tolocal c = redis.call('SINTER', s1, s2, s3) but doesn't and is my problem.
(This is a controlled app, so it'd be impossible to pick a set variable that doesn't exist or is empty. It's possible to get an empty intersection, but that's not the problem here. I just can't seem to pass dynamically selected myVar1, myVar2, myVar3 to EVAL unless they are string literals, which I don't know ahead of time.)
As to the SINTER KEYS issue, is the name of the SET considered the KEY? If so, the ARGV is the actual contents?
In that case, in db.EVAL(rs, 0 , myVar1, myVar2, myVar3, function(err, replies) { …
myVar1, myVar2, myVar3 would/should be considered KEYS, no?
local c = redis.call('SINTER', unpack(ARGV)) does work to unpack(KEYS) instead of ARGVs (when I use string literals 's1', 's2' and 's3'). I don't know why. Is there an unpack(KEYS) command or are KEYS passed considered ARGVs in this case?
Thanks.
Sorry, thanks for the pointers, perhaps I wasn't clear.
's1', 's2' and 's3' are in fact the names of 3 sets is Redis. What are 'passed as variables' above within the EVAL statement in fact resolve to string variables 's1', 's2' and 's3'. Easily verified with SMEMBERS to see they are populated and also SINTER s1 s2 s3 does in fact give the right intersection, as I mentioned above. I've checked this with lua script loaded and ran via redis-cli, also sent via a Node.js script. That's not the problem I'm having.
To state slightly more narrowly:
db.EVAL(rs, 0 , 's1', 's2', 's3', function(err, replies) { … => works in every way.
But
myVar1 = 's1';
myVar2 = 's2';
myVar3 = 's3';
db.EVAL(rs, 0 , myVar1, myVar2, myVar3, function(err, replies) { … => does NOT work
db.EVAL(rs, 3 , myVar1, myVar2, myVar3, function(err, replies) { … => does NOT work either
I just want to call in Node.js:
db.EVAL(rs, 0 , myVar1, myVar2, myVar3, function(err, replies) { …and use in lua script in Node.js:local c = redis.call('SINTER', unpack(ARGV)) which should unpack tolocal c = redis.call('SINTER', s1, s2, s3) but doesn't and is my problem.
(This is a controlled app, so it'd be impossible to pick a set variable that doesn't exist or is empty. It's possible to get an empty intersection, but that's not the problem here. I just can't seem to pass dynamically selected myVar1, myVar2, myVar3 to EVAL unless they are string literals, which I don't know ahead of time.)
As to the SINTER KEYS issue, is the name of the SET considered the KEY? If so, the ARGV is the actual contents?
In that case, in db.EVAL(rs, 0 , myVar1, myVar2, myVar3, function(err, replies) { …
myVar1, myVar2, myVar3 would/should be considered KEYS, no?
local c = redis.call('SINTER', unpack(ARGV)) does work to unpack(KEYS) instead of ARGVs (when I use string literals 's1', 's2' and 's3'). I don't know why. Is there an unpack(KEYS) command or are KEYS passed considered ARGVs in this case?
Thanks.
s1 = 's1';s2 = 's2';s3 = 's3';
db.eval(rs, 0 , 's1', 's2', 's3' , function(err, replies) {… => everything is passed to lua, and in lua this:
c = redis.call('SINTER', unpack(ARGV)) also works and generates the correct intersection of the 3 SETs
db.eval(rs, 0 , s1, s2, s3 , function(err, replies) {… => fails
c = redis.call('SINTER', unpack(ARGV)) => fails
db.eval(rs, 3 , s1, s2, s3 , function(err, replies) {… => fails
c = redis.call('SINTER', unpack(ARGV)) => fails
v1 = 's1';v2 = 's2';v3 = 's3';
db.eval(rs, 0 , v1, v2, v3 , function(err, replies) {… => works in combo with:
c = redis.call('SINTER', unpack(ARGV)) => generates exactly what's expected.
db.eval(rs, 2 , v1, v2, function(err, replies) {… combo with:
c = redis.call('SINTER', unpack(KEYS)) => works.
db.eval(rs, 3 , v1, v2, v3 , function(err, replies) {… combo with:
c = redis.call('SINTER', unpack(KEYS)) => works.
var myArgsTable = ['v1', 'v2', 'v3'];var length = myArgsTable.length;db.eval(rs, length, myArgsTable, function(err, replies) {… fails with "[Error: ERR Number of keys can't be greater than number of args]" showing myArgsTable doesn't translate into 'v1', 'v2', 'v3' unsurprisingly.
Here's where I originally got stuck, while testing:s1 = 's1';s2 = 's2';s3 = 's3';('s1', 's2' and 's3' are in fact the names of 3 actual SETS in Redis.)If I pass string literals to get at those sets like so:db.eval(rs, 0 , 's1', 's2', 's3' , function(err, replies) {… => everything is passed to lua, and in lua this:c = redis.call('SINTER', unpack(ARGV)) also works and generates the correct intersection of the 3 SETsif however I pass the variables created in JS above:db.eval(rs, 0 , s1, s2, s3 , function(err, replies) {… => failsc = redis.call('SINTER', unpack(ARGV)) => failsdb.eval(rs, 3 , s1, s2, s3 , function(err, replies) {… => failsc = redis.call('SINTER', unpack(ARGV)) => failsEven though I've been on pain killers in the last 36 hours, I thought this was nuts.So I thought perhaps naming the variables the same as quoted string literals may have been the oversight.
Renamed them:
v1 = 's1';v2 = 's2';v3 = 's3';Lo and behold, this works:db.eval(rs, 0 , v1, v2, v3 , function(err, replies) {… => works in combo with:c = redis.call('SINTER', unpack(ARGV)) => generates exactly what's expected.As you point out, I was not clear on KEYS/ARGV business, mostly because I didn't know unpack(KEYS) existed and was forcing the notion of ARGV into my model. Sodb.eval(rs, 2 , v1, v2, function(err, replies) {… combo with:c = redis.call('SINTER', unpack(KEYS)) => works.And so does:db.eval(rs, 3 , v1, v2, v3 , function(err, replies) {… combo with:c = redis.call('SINTER', unpack(KEYS)) => works.Finally, I'm still groggy but happy it got sorted, thanks for your guidance.
One final question on this:
var myArgsTable = ['v1', 'v2', 'v3'];var length = myArgsTable.length;db.eval(rs, length, myArgsTable, function(err, replies) {… fails with "[Error: ERR Number of keys can't be greater than number of args]" showing myArgsTable doesn't translate into 'v1', 'v2', 'v3' unsurprisingly.Can you think of a way to insert a variable number of KEYS into the EVAL call?
var length = myArgsTable.length;db.eval(rs, length, myArgsTable, function(err, replies) {… fails with "[Error: ERR Number of keys can't be greater than number of args]" showing myArgsTable doesn't translate into 'v1', 'v2', 'v3' unsurprisingly.Can you think of a way to insert a variable number of KEYS into the EVAL call?Yes, one of these might work, or you may need to pass something else as the first argument to apply:db.eval.apply(undefined, [rs, length] + myArgsTable + [function(err, replies) {...}]);db.eval.apply(db, [rs, length] + myArgsTable + [function(err, replies) {...}]);
It would seem that you can use:
db.eval([rs, length] + myArgsTable. function(err, replies) {...});
var myArgsTable = ['v1', 'v2', 'v3'…];
var length = myArgsTable.length;
myArgsTable = [rs, length].concat(myArgsTable);db.eval(myArgsTable, function(err, replies) {...}); //single array variable
--