2016-06-05 2 views
0

У меня есть Redis с большим количеством ключей в некотором формате, и я хочу получить ключи, которые соответствуют некоторому шаблону и выполнять некоторые операции над ними. Я не использую метод KEYS, так как он не рекомендуется в производстве. Использование SCAN. Мне интересно, как лучше всего написать код. Я должен сделать что-то вроде время цикла, но с помощью обещаний, мое текущее решение выглядит следующим образом (код упрощен немного):Использование Redis SCAN в NODE

'use strict' 
const Promise = require('bluebird'); 
const config = require('./config'); 
const client = require('./clinet'); 

let iterator = 0; 
Promise.coroutine(function*() { 
    do { 
    iterator = yield clinet.scanAsync(iterator, 'myQuery', 'COUNT', config.scanChunkSize) 
     .then(data => { 
     let nextIterator = data[0]; 
     let values = data[1]; 
     //do some magic with values 
     return nextIterator; 
     }) 
    } while (iterator !== '0'); 
})(); 

Есть ли лучший способ сделать это, что я не хватает?

ответ

0

Пройдитесь через это, это может помочь.

https://github.com/fritzy/node-redisscan

не использовать библиотеку, как это, пройти через код, доступный в https://github.com/fritzy/node-redisscan/blob/master/index.js

+0

Поскольку в «do magic line» у меня много операций, основанных на обещаниях, я хотел избежать передачи обратных вызовов и смешивания, но сделать это более дружелюбно. – Madbrush

1

Вы можете использовать рекурсию, чтобы держать вызов сканирования пока не сделано.

function scanAsync(cursor, pattern, returnSet){ 

    return redisClient.scanAsync(cursor, "MATCH", pattern, "COUNT", "100").then(
     function (reply) { 

      cursor = reply[0]; 
      var keys = reply[1]; 
      keys.forEach(function(key,i){ 
       returnSet.add(key); 
      }); 

      if(cursor === '0'){ 
       return Array.from(returnSet); 
      }else{ 
       return scanAsync(cursor, pattern, returnSet) 
      } 

    }); 
} 

Pass в наборе(), чтобы убедиться, что ключи не дублируются

myResults = new Set(); 

scanAsync('0', "NOC-*[^listen]*", myResults).map( 
    function(myResults){ console.log(myResults); } 
); 
1

Вы можете попробовать этот фрагмент кода для scan (1000) ключей на итерации и «delete`.

var cursor = '0'; 
function scan(pattern,callback){ 

    redisClient.scan(cursor, 'MATCH',pattern,'COUNT', '1000', function(err, reply){ 
    if(err){ 
     throw err; 
    } 
    cursor = reply[0]; 
    if(cursor === '0'){ 
     return callback(); 
    }else{ 

     var keys = reply[1]; 
     keys.forEach(function(key,i){     
      redisClient.del(key, function(deleteErr, deleteSuccess){ 
       console.log(key); 
      }); 
     }); 


     return scan(pattern,callback); 
    } 
    }); 
} 

scan(strkey,function(){ 
    console.log('Scan Complete'); 
}); 
Смежные вопросы