CouchDB,Node.js,摇篮 – 如何根据返回的数据获取数据

我正在使用node.js +摇篮和couchdb的消息系统。

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

这是我能够做到我所需要的唯一途径,但却是非常低效的

私人消息/所有密钥=消息收件人的用户名

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

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

谢谢

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

 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是一个很好的文档数据库,但是您应该经常更新现有文档,因为它会在每次更新后创build一个全新的文档版本(这是因为MVCC模型用于实现高可用性和数据持久性)。 这种行为的后果是更高的磁盘空间消耗(更多的数据/更新,需要更多的磁盘空间 – 例如 ),所以你应该看它并相应地运行数据库消耗。

我认为你的系统可以使用内存hashmap,如memcached。 每个用户状态条目将在时间限制后过期。 映射将是[用户 – > lasttimeseen]

如果hashmap包含用户,那么用户在线。 在某些操作上,刷新最后一次。

然后每次只能查询地图本身并返回结果。

我想起了这个演讲:

数据库吸引消息

而来自Tim O'Reilly的报价:

“周一,friendfeed对45000个用户进行了近300万次的flickr调查,其中只有6K的用户login。”build筑不匹配“。

正如在其他答案中指出的那样,CouchDB的更新是昂贵的,如果可能的话应该避免,并且可能不需要这些数据是持久的。 caching或消息传递系统可以更加优雅和高效地解决您的问题。