Более чистый способ выполнить несколько запросов redis в node.js - PullRequest
1 голос
/ 22 ноября 2011

Я сделал некоторый код node.js для извлечения данных из базы данных Redis, но я не очень доволен, и я хотел бы улучшить его ...
По сути, у меня есть запись "люди" в моем Redis DB. От «people» я получаю список «person: i» (i - целое число), и для каждого «person: i» я делаю дополнительный запрос для получения хэша с ключом «person: i».

Вот как я это делаю:

db.smembers("people", function(err1, people){
  var jsonObj;
  var jsonArr = [];
  if(!err1) {
    var i = 0;
    res.writeHead(200, {'content-type': 'application/json'});
    // people will provide a list like [person:1, person:2, ..., person:n]
    people.forEach(function(person){
      // In redis I get the hash with key "person:i" 
      db.hgetall(person, function(err2,obj){
        if(!err2){
          // Add person into array
          jsonArr.push({ "id" : person.substring(7), "lastname" : obj["lastname"], "firstname" : obj["firstname"]});

          // I'm not happy with this part where I check if I reached the last item of people array....
          i = i + 1;
          if(i == people.length){
            res.write(JSON.stringify(jsonArr));
            res.end();
          }
        } else {
          var jsonObj = { "error" : "database error", "message" : "Cannot get hash " + person}; 
          res.write(JSON.stringify(jsonObj));
          res.end();
        }
      });
    });
  } else {
    jsonObj = { "error" : "database error", "message" : err1.message };
    res.writeHead(200, {'content-type': 'application/json'});
    res.write(JSON.stringify(jsonObj));
    res.end();
  }
});

Каким был бы самый чистый (хотя бы более чистый) способ сделать это?

1 Ответ

4 голосов
/ 22 ноября 2011

То, что вы ищете, это асинхронная система управления потоком. Примером может быть Step или streamline.js .

Альтернативой может быть абстрагирование процесса, создание модели данных для Person, которая будет извлекать отдельный объект person, и модели People, представляющей собой коллекцию Person, которая будет включать в себя метод выборки нескольких людей, следующих структуре использование.

Редактировать: Я нашел полный список совместимых с узлами потоков управления / асинхронных библиотек: https://github.com/joyent/node/wiki/modules#wiki-async-flow

Редактировать: После просмотра вашего кода я подумал о другом альтернативном методе, который довольно специфичен для этого случая, но не напрямую затрагивает природу вопроса управления потоком.

Изменяя вашу схему для сохранения только идентификатора человека в ключе people, вы открываете себя для использования команды SORT redis, которая позволяет получать всю коллекцию в единая команда Для этого в Redis:

> SADD people 1 2 3 4
> HMSET person:1 firstname John lastname Smith
> HMSET person:2 firstname Jane lastname Smith
> HMSET person:3 firstname John lastname Doe
> HMSET person:4 firstname Jane lastname Doe
> SORT people GET # GET person:*->firstname GET person:*->lastname
 1) "1"
 2) "Jane"
 3) "Doe"
 4) "2"
 5) "Jane"
 6) "Smith"
 7) "3"
 8) "John"
 9) "Doe"
10) "4"
11) "Jane"
12) "Doe"

Это дает дополнительное преимущество экономии памяти с помощью клавиши people и позволяет разбивать на страницы / сортировать с помощью параметров by команды *1027* и limit.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...