2013-12-18 5 views
1

Я хочу сделать вставку в моем MongoDB, но она становится довольно сложной, и это простая операция, поэтому я думаю, что я потерялся в какой-то момент.MongoDB с запросами Node.js db

У меня есть три коллекции, которые я упрощу ради этого вопроса: сайты, клиенты, черный список.

Когда новый Клиент подписывается, она мгновенно получает Сайт. Поэтому мне нужно проверить форму, если Клиент не существует, тогда, если адрес электронной почты Клиента не был внесен в черный список, тогда, если сайт не существует, и, наконец, создайте элементы Клиент & Сайт.

Я начал делать это с помощью обратных вызовов, но это, кажется, overcomplciated для меня сделать так:

var input = {...}; //assume here I have all the user input 
db.collection('Clients').count({'email', input.email}, {limit: 1}, function (err, count) { 
    if (count > 0) { 
     db.collection('Blacklist').count({'email', input.email}, {limit: 1}, function (err, count) { 
      if (count > 0) { 
       db.collection('Sites').count({'domain', input.domain}, {limit: 1}, function (err, count) { 
        if (count > 0) { 
         // CREATE THE ACCOUNT 
        } else { 
         res.send("Site already exists."); 
        } 
        db.close(); 
       }); 
      } else { 
       res.send("Client is blacklisted."); 
      } 
      db.close(); 
     }); 
    } else { 
     res.send("Client already exists."); 
    } 
    db.close(); 
}); 

Любой другой способ для того чтобы достигнуть такого рода операций с легкостью?

Идеально для меня было бы что-то вроде:

var input = {...}; //assume here I have all the user input 
if (db.collection('Clients').count({'email', input.email}, {limit: 1}) == 0 && 
    db.collection('Blacklist').count({'email', input.email}, {limit: 1}) == 0 && 
    db.collection('Sites').count({'domain', input.domain}, {limit: 1}) == 0) { 
    // INSERT HERE 
} else { 
    res.send("Could not insert"); 
} 

ответ

1

Вы можете использовать async. как это:

var input = {...}; //assume here I have all the user input 
var validate = function (input, callback) { 
    async.parallel({ 
     clientExists: function(cb) { 
      db.collection('Clients').count({'email', input.email}, {limit: 1}, cb) 
     }, 
     blacklisted: function(cb) { 
      db.collection('Blacklist').count({'email', input.email}, {limit: 1}, cb) 
     }, 
     siteExists: function(cb) { 
      db.collection('Sites').count({'domain', input.domain}, {limit: 1}, cb) 
     }, 
    }, function(error, result) { 
     db.close(); 

     if (error) { 
      return callback({ 
       message: 'Server error', 
       error: error 
      }); 
     } 

     if (result.clientExists > 0) { 
      return callback({ 
       message: 'Client already exists', 
      }); 
     } 

     if (result.siteExists > 0) { 
      return callback({ 
       message: 'Site already exists', 
      }); 
     } 

     if (result.blacklisted > 0) { 
      return callback({ 
       message: 'Client is blacklisted', 
      }); 
     } 

     callback(null, true) 
    }) 
} 

validate(input, function (error, success) { 
    if (error) { 
     return res.send(error.message) 
    } 

    //CREATE ACCOUNT HERE! 
}) 
3

программирование Node очень отличается от последовательного программирования.

Вы можете использовать async или другую библиотеку последовательной абстракции, например, например. Seq.

Если вы не боитесь погрузиться глубоко, вы можете включить «Гармонию» (и использовать режущую версию Node.js) и работать с генераторами и обещаниями. С этим можно написать код, который выглядит как последовательный код.

Но кажется, что вам лучше использовать async. Потребуется немного времени, чтобы привыкнуть к нему, но через некоторое время вы читаете и пишете код, не задумываясь.

И в вашем специальном случае другим способом решить эту проблему было бы полное изменение схемы базы данных. Почему бы не иметь только и Blacklists коллекцию и переместить содержимое коллекции Sites непосредственно клиенту в виде вложенных документов? Конечно, это сильно зависит от ваших случаев использования и обычно не может рассматриваться как лучшее решение.

+0

ну, я хочу быть асинхронными, но я не знаю точно, как стрелять эти три операции, а затем, когда все они завершены, выполнить обратный вызов. Возможно, что «асинк», предложенный Красу, - это путь. Спасибо :) –

+0

Мы оба предложили использовать async. И @krasu была настолько умна, чтобы дать вам решение, которое, надеюсь, поможет вам больше, чем мои теплые слова ;-) – hgoebl

Смежные вопросы