javascript - CouchDB、Node.js、Cradle——如何根据返回的数据获取数据

标签 javascript node.js couchdb cradle

我正在使用 node.js + cradle 和 couchdb 开发消息系统。

当用户提取他们的消息列表时,我需要提取向他们发送消息的用户的在线状态。每个注册用户的在线状态存储在用户文档中,消息信息存储在单独的文档中。

这是我能设法完成我需要的唯一方法,但效率极低

privatemessages/all key = 消息接收者的用户名

db.view('privatemessages/all', {"key":username}, function (err, res) {
    res.forEach(function (rowA) {
        db.view('users/all', {"key":rowA.username}, function (err, res) {
            res.forEach(function (row) {
                result.push({onlinestatus:row.onlinestatus, messagedata: rowA});
            });
        });
    });

    response.end(JSON.stringify(result));
});

有人能告诉我正确的做法吗?

谢谢

最佳答案

您的代码可能会返回空结果,因为您在可能尚未从数据库中获取用户状态时调用响应。另一个问题是,如果我收到来自同一用户的多条消息,那么调用他的状态可能是口是心非的。下面是一个函数,它首先从数据库中获取消息以避免用户口是心非,然后获取他们的状态。

function getMessages(username, callback) {
    // this would be "buffer" for senders of the messages
    var users = {};
    // variable for a number of total users I have - it would be used to determine
    // the callback call because this function is doing async jobs
    var usersCount = 0;
    // helpers vars
    var i = 0, user, item;

    // get all the messages which recipient is "username"
    db.view('privatemessages/all', {"key":username}, function (errA, resA) {
        // for each of the message
        resA.forEach(function (rowA) {
            user = users[rowA.username];
            // if user doesn't exists - add him to users list with current message
            // else - add current message to existing user
            if(!user) {
                users[rowA.username] = {
                    // I guess this is the name of the sender
                    name: rowA.username,
                    // here will come his current status later
                    status: "",
                    // in this case I may only need content, so there is probably 
                    // no need to insert whole message to array
                    messages: [rowA]
                };
                usersCount++;
            } else {
                user.messages.push(rowA);
            }
        });

        // I should have all the senders with their messages
        // and now I need to get their statuses
        for(item in users) {
            // assuming that user documents have keys based on their names
            db.get(item, function(err, doc) {
                i++;
                // assign user status
                users[item].status = doc.onlineStatus;
                // when I finally fetched status of the last user, it's time to
                // execute callback and rerutn my results
                if(i === usersCount) {
                    callback(users);
                }
            });
        }
    });
}

...

getMessages(username, function(result) {
    response.end(JSON.stringify(result));
});

虽然 CouchDB 是一个很棒的文档数据库,但您应该小心频繁更新现有文档,因为它会在每次更新后创建全新的文档版本(这是因为它的 MVCC 模型用于实现高可用性和数据持久性).此行为的结果是更高的磁盘空间消耗(更多数据/更新,需要更多磁盘空间 - example),因此您应该观察它并相应地运行数据库消耗。

关于javascript - CouchDB、Node.js、Cradle——如何根据返回的数据获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7022580/

相关文章:

couchdb - 使用 jsonp 响应将数据添加到 couchdb

javascript - 在这种情况下热衷于将字符串拆分为数组吗?

javascript - 固定的滚动顶部菜单不允许到达屏幕底部

javascript - Angular 、 promise 和异步功能

html - 该值不会从下拉列表发送到 Express.js

javascript - Node js + 多个带回调的嵌套内部函数

javascript - 为什么我收到 UnhandledPromiseRejectionWarning : Unhandled promise rejection?

couchdb - 如何在不丢失现有附件的情况下更新 couchdb 文档

node.js - CouchDB 和 Node.js - 你推荐什么模块?

javascript - JavaScript 中 "anonymous function"和 "function literal"的区别?