首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >CouchDB,Node.js,Cradle -如何基于返回的数据获取数据

CouchDB,Node.js,Cradle -如何基于返回的数据获取数据
EN

Stack Overflow用户
提问于 2011-08-11 07:54:54
回答 3查看 2.2K关注 0票数 1

我正在开发一个使用node.js +摇篮和couchdb的消息传递系统。

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

这里的是我唯一能做我需要的事情的方法,但是它的效率极低的

私钥/所有密钥=消息接收者的用户名

代码语言:javascript
复制
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));
});

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

谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-08-11 09:21:50

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

代码语言:javascript
复制
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模型,用于实现高可用性和数据持久性)。这种行为的结果是更高的磁盘空间消耗(更多的数据/更新,需要更多的磁盘空间-- 示例),因此您应该观察它并相应地运行数据库消耗。

票数 1
EN

Stack Overflow用户

发布于 2011-08-11 08:00:03

我认为您的系统可以使用内存中的hashmap,比如memcached。每个用户状态项将在一个时间限制后过期。映射将是用户-> lasttimeseen。

如果hashmap包含用户,则该用户处于联机状态。在某些特定的操作中,刷新最后的时间。

然后,不要每次点击整个世界,只需查询地图本身并返回结果。

票数 1
EN

Stack Overflow用户

发布于 2011-08-12 05:07:43

我想起了这个演讲:

用于消息传递的数据库

它引用了蒂姆·奥莱利的话:

“周一,friendfeed对45000名用户进行了近300万次的闪烁调查,其中只有6K用户登录。架构不匹配。”

正如在其他答案中所指出的,CouchDB中的更新是昂贵的,如果可能的话,应该避免更新,而且这些数据可能不需要持久化。缓存或消息传递系统可以更优雅、更有效地解决问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7022580

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档