CouchDB, Node.js, Cradle -如何根据返回的数据获取数据
CouchDB, Node.js, Cradle - How to get data based on returned data
我正在开发一个使用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模型用于实现高可用性和数据持久性)。这种行为的后果是更高的磁盘空间消耗(更多的数据/更新,需要更多的磁盘空间-示例),因此应该观察它并相应地运行数据库消耗。
我认为您的系统可以使用内存中的哈希映射,如memcached。每个用户状态条目将在一个时间限制之后过期。映射是[user -> lasttimeseen]
如果hashmap包含该用户,则该用户在线。对于某些操作,刷新lasttimeseen。
然后,不是每次ping整个世界,只是查询映射本身并返回结果。
我想起了这个演讲:
数据库不适合消息传递
引用Tim O'Reilly的话:
"周一,friendfeed对45000名用户进行了近300万次调查,其中只有6K人登录了。体系结构不匹配。"
正如在其他答案中指出的那样,CouchDB中的更新是昂贵的,应该尽可能避免,并且可能不需要将此数据持久化。缓存或消息传递系统可以更优雅、更有效地解决问题。
- 使用jquery将mysql数据获取到新的表行中
- 使用createContainer将Meteor数据获取到React Native中时出现问题
- AJAX调用并在Node中获取返回数据
- 角度服务未返回数据
- 创建按钮,根据表单字段中的数据获取特定的URL
- 统计ajax返回数据中的html元素
- 将JSON API数据获取到html
- 将json数据获取到数组中
- 有没有更好的方法可以测量从Ajax调用返回数据所需的总时间
- Imgur API图像搜索未返回数据
- javascript对象显示为null,但object.properties返回数据
- 如何从ajax调用JQuery返回数据
- 试图从嵌套的回调函数返回数据
- NodeJS FS 不从多个文件返回数据
- 返回之前获取数据服务器端
- Ajax 发布到 PHP 并获取返回数据
- 用JSON返回数据填充jqGrid并获取Uncaught TypeError无法读取属性'0'的未定义
- Android和JavaScript,JS如何获取webview JS返回数据
- 在Asp.Net中获取jQueryAjax返回数据
- CouchDB, Node.js, Cradle -如何根据返回的数据获取数据