diff --git a/src/database/mongo/sorted.js b/src/database/mongo/sorted.js index 49b5862fe2..22c7e44196 100644 --- a/src/database/mongo/sorted.js +++ b/src/database/mongo/sorted.js @@ -41,6 +41,22 @@ module.exports = function (db, module) { key = { $in: key }; } + if (start < 0 && start > stop) { + return callback(null, []); + } + + var reverse = false; + if (start === 0 && stop < -1) { + reverse = true; + sort *= -1; + start = Math.abs(stop + 1); + stop = -1; + } else if (start < 0 && stop > start) { + var tmp1 = Math.abs(stop + 1); + stop = Math.abs(start + 1); + start = tmp1; + } + var limit = stop - start + 1; if (limit <= 0) { limit = 0; @@ -54,7 +70,9 @@ module.exports = function (db, module) { if (err || !data) { return callback(err); } - + if (reverse) { + data.reverse(); + } if (!withScores) { data = data.map(function (item) { return item.value; diff --git a/test/database/sorted.js b/test/database/sorted.js index c5f7101aff..703d3e93b4 100644 --- a/test/database/sorted.js +++ b/test/database/sorted.js @@ -78,6 +78,49 @@ describe('Sorted Set methods', function () { done(); }); }); + + it('should handle negative start/stop', function (done) { + db.sortedSetAdd('negatives', [1, 2, 3, 4, 5], ['1', '2', '3', '4', '5'], function (err) { + assert.ifError(err); + db.getSortedSetRange('negatives', -2, -4, function (err, data) { + assert.ifError(err); + assert.deepEqual(data, []); + done(); + }); + }); + }); + + it('should handle negative start/stop', function (done) { + db.getSortedSetRange('negatives', -4, -2, function (err, data) { + assert.ifError(err); + assert.deepEqual(data, ['2', '3', '4']); + done(); + }); + }); + + it('should handle negative start/stop', function (done) { + db.getSortedSetRevRange('negatives', -4, -2, function (err, data) { + assert.ifError(err); + assert.deepEqual(data, ['4', '3', '2']); + done(); + }); + }); + + it('should handle negative start/stop', function (done) { + db.getSortedSetRange('negatives', -5, -1, function (err, data) { + assert.ifError(err); + assert.deepEqual(data, ['1', '2', '3', '4', '5']); + done(); + }); + }); + + it('should handle negative start/stop', function (done) { + db.getSortedSetRange('negatives', 0, -2, function (err, data) { + assert.ifError(err); + assert.deepEqual(data, ['1', '2', '3', '4']); + done(); + }); + }); }); describe('getSortedSetRevRange()', function () {