具有Node.js数据库查询的MongoDB

时间:2013-12-18 12:01:07

标签: javascript node.js mongodb

我想在我的MongoDB中插入一个插件,但它变得非常复杂,这是一个简单的操作,所以我觉得我在某些时候丢失了。

我有三个系列,为了解决这个问题我会简化:网站,客户,黑名单。

当新客户注册时,她会立即获得一个网站。因此我需要从表单中检查,如果客户端不存在,那么如果客户端电子邮件未被列入黑名单,那么如果该站点不存在,最后创建元素Client&站点。

我开始通过回调来做到这一点,但对我来说这似乎过于简单:

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");
}

2 个答案:

答案 0 :(得分:3)

节点编程与顺序编程非常不同。

您可以使用async或其他顺序抽象库,例如Seq

如果你不担心深入潜水,你可以启用'Harmony'(并使用最新版本的Node.js)并使用Generators和Promises。有了这个,就可以编写看起来像顺序代码的代码。

但是现在看来你最好使用async。它需要一点时间来适应它,但过了一段时间你不经过深思熟虑地阅读和编写代码。

在您的特殊情况下,解决此问题的另一种方法是完全更改数据库架构。为什么不只有ClientsBlacklists集合,并将Sites集合的内容作为嵌入文档直接移动到客户端?当然,这在很大程度上取决于您的使用情况,通常不能被视为更好的解决方案。

答案 1 :(得分: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!
})