optimize getPostSummaryByPids

v1.18.x
barisusakli 11 years ago
parent 1a68fe5a26
commit eeb4c9f487

@ -1,5 +1,7 @@
"use strict";
var async = require('async');
module.exports = function(db, module) {
var helpers = module.helpers.mongo;
@ -119,6 +121,17 @@ module.exports = function(db, module) {
});
}
module.sortedSetsRanks = function(keys, values, callback) {
var data = new Array(values.length);
for (var i=0; i<values.length; ++i) {
data[i] = {key: keys[i], value: values[i]};
}
async.map(data, function(item, next) {
getSortedSetRank(module.getSortedSetRange, item.key, item.value, next);
}, callback);
};
module.sortedSetScore = function(key, value, callback) {
value = helpers.valueToString(value);
db.collection('objects').findOne({_key:key, value: value}, {fields:{score:1}}, function(err, result) {

@ -54,6 +54,14 @@ module.exports = function(redisClient, module) {
redisClient.zrank(key, value, callback);
};
module.sortedSetsRanks = function(keys, values, callback) {
var multi = redisClient.multi();
for(var i=0; i<values.length; ++i) {
multi.zrank(keys[i], values[i]);
}
multi.exec(callback);
};
module.sortedSetRevRank = function(key, value, callback) {
redisClient.zrevrank(key, value, callback);
};

@ -265,87 +265,125 @@ var async = require('async'),
options.stripTags = options.hasOwnProperty('stripTags') ? options.stripTags : false;
options.parse = options.hasOwnProperty('parse') ? options.parse : true;
function getPostSummary(post, callback) {
var keys = pids.map(function(pid) {
return 'post:' + pid;
});
db.getObjectsFields(keys, ['pid', 'tid', 'content', 'uid', 'timestamp', 'deleted'], function(err, posts) {
if (err) {
return callback(err);
}
post.relativeTime = utils.toISOString(post.timestamp);
posts = posts.filter(function(p) {
return !!p && parseInt(p.deleted, 10) !== 1;
});
var uids = [], tids = [];
for(var i=0; i<posts.length; ++i) {
if (uids.indexOf(posts[i].uid) === -1) {
uids.push(posts[i].uid);
}
if (tids.indexOf('topic:' + posts[i].tid) === -1) {
tids.push('topic:' + posts[i].tid);
}
}
async.parallel({
user: function(next) {
user.getUserFields(post.uid, ['username', 'userslug', 'picture'], next);
users: function(next) {
user.getMultipleUserFields(uids, ['uid', 'username', 'userslug', 'picture'], next);
},
topicCategory: function(next) {
topics.getTopicFields(post.tid, ['title', 'cid', 'slug', 'deleted'], function(err, topicData) {
topicsAndCategories: function(next) {
db.getObjectsFields(tids, ['tid', 'title', 'cid', 'slug', 'deleted'], function(err, topics) {
if (err) {
return next(err);
} else if (parseInt(topicData.deleted, 10) === 1) {
return callback();
}
categories.getCategoryFields(topicData.cid, ['name', 'icon', 'slug'], function(err, categoryData) {
if (err) {
return next(err);
}
topicData.title = validator.escape(topicData.title);
var cidKeys = topics.map(function(topic) {
return 'category:' + topic.cid;
}).filter(function(value, index, array) {
return array.indexOf(value) === index;
});
next(null, {topic: topicData, category: categoryData});
db.getObjectsFields(cidKeys, ['cid', 'name', 'icon', 'slug'], function(err, categories) {
next(err, {topics: topics, categories: categories});
});
});
},
content: function(next) {
if (!post.content || !options.parse) {
return next(null, post.content);
indices: function(next) {
var pids = [], keys = [];
for (var i=0; i<posts.length; ++i) {
pids.push(posts[i].pid);
keys.push('tid:' + posts[i].tid + ':posts');
}
postTools.parse(post.content, next);
},
index: function(next) {
Posts.getPidIndex(post.pid, next);
db.sortedSetsRanks(keys, pids, next);
}
}, function(err, results) {
function toObject(key, data) {
var obj = {};
for(var i=0; i<data.length; ++i) {
obj[data[i][key]] = data[i];
}
return obj;
}
if (err) {
return callback(err);
}
post.user = results.user;
post.topic = results.topicCategory.topic;
post.category = results.topicCategory.category;
post.index = results.index;
results.users = toObject('uid', results.users);
results.topics = toObject('tid', results.topicsAndCategories.topics);
results.categories = toObject('cid', results.topicsAndCategories.categories);
if (options.stripTags && results.content) {
var s = S(results.content);
post.content = s.stripTags.apply(s, utils.stripTags).s;
} else {
post.content = results.content;
for(var i=0; i<posts.length; ++i) {
if (!utils.isNumber(results.indices[i])) {
posts[i].index = 1;
} else {
posts[i].index = parseInt(results.indices[i], 10) + 2;
}
}
callback(null, post);
});
}
async.map(posts, function(post, next) {
if (parseInt(results.topics[post.tid].deleted, 10) === 1) {
return next();
}
var keys = pids.map(function(pid) {
return 'post:' + pid;
});
post.user = results.users[post.uid];
post.topic = results.topics[post.tid];
post.category = results.categories[post.topic.cid];
db.getObjectsFields(keys, ['pid', 'tid', 'content', 'uid', 'timestamp', 'deleted'], function(err, posts) {
if (err) {
return callback(err);
}
post.topic.title = validator.escape(post.topic.title);
post.relativeTime = utils.toISOString(post.timestamp);
posts = posts.filter(function(p) {
return !!p && parseInt(p.deleted, 10) !== 1;
});
if (!post.content || !options.parse) {
return next(null, post);
}
async.map(posts, getPostSummary, function(err, posts) {
if (err) {
return callback(err);
}
postTools.parse(post.content, function(err, content) {
if (err) {
return next(err);
}
posts = posts.filter(function(post) {
return !!post;
});
if (options.stripTags && content) {
var s = S(content);
post.content = s.stripTags.apply(s, utils.stripTags).s;
} else {
post.content = content;
}
return callback(null, posts);
next(null, post);
});
}, function(err, posts) {
if (err) {
return callback(err);
}
posts = posts.filter(function(post) {
return !!post;
});
callback(null, posts);
});
});
});
};

Loading…
Cancel
Save