mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-10 07:55:46 +01:00
optimize suggested topics/search
This commit is contained in:
@@ -17,7 +17,7 @@ var search = module.exports;
|
|||||||
search.search = function (data, callback) {
|
search.search = function (data, callback) {
|
||||||
var start = process.hrtime();
|
var start = process.hrtime();
|
||||||
data.searchIn = data.searchIn || 'titlesposts';
|
data.searchIn = data.searchIn || 'titlesposts';
|
||||||
|
data.sortBy = data.sortBy || 'relevance';
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
if (data.searchIn === 'posts' || data.searchIn === 'titles' || data.searchIn === 'titlesposts') {
|
if (data.searchIn === 'posts' || data.searchIn === 'titles' || data.searchIn === 'titlesposts') {
|
||||||
@@ -39,10 +39,14 @@ search.search = function (data, callback) {
|
|||||||
|
|
||||||
function searchInContent(data, callback) {
|
function searchInContent(data, callback) {
|
||||||
data.uid = data.uid || 0;
|
data.uid = data.uid || 0;
|
||||||
var matchCount = 0;
|
|
||||||
var pids;
|
var pids;
|
||||||
var metadata;
|
var metadata;
|
||||||
var itemsPerPage = Math.min(data.itemsPerPage || 10, 100);
|
var itemsPerPage = Math.min(data.itemsPerPage || 10, 100);
|
||||||
|
const returnData = {
|
||||||
|
posts: [],
|
||||||
|
matchCount: 0,
|
||||||
|
pageCount: 1,
|
||||||
|
};
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
async.parallel({
|
async.parallel({
|
||||||
@@ -72,8 +76,13 @@ function searchInContent(data, callback) {
|
|||||||
},
|
},
|
||||||
function (results, next) {
|
function (results, next) {
|
||||||
pids = results.pids;
|
pids = results.pids;
|
||||||
|
|
||||||
|
if (data.returnIds) {
|
||||||
|
return callback(null, results);
|
||||||
|
}
|
||||||
|
|
||||||
if (!results.pids.length && !results.tids.length) {
|
if (!results.pids.length && !results.tids.length) {
|
||||||
return callback(null, { posts: [], matchCount: matchCount, pageCount: 1 });
|
return callback(null, returnData);
|
||||||
}
|
}
|
||||||
|
|
||||||
topics.getMainPids(results.tids, next);
|
topics.getMainPids(results.tids, next);
|
||||||
@@ -93,28 +102,30 @@ function searchInContent(data, callback) {
|
|||||||
},
|
},
|
||||||
function (_metadata, next) {
|
function (_metadata, next) {
|
||||||
metadata = _metadata;
|
metadata = _metadata;
|
||||||
matchCount = metadata.pids.length;
|
returnData.matchCount = metadata.pids.length;
|
||||||
|
returnData.pageCount = Math.max(1, Math.ceil(parseInt(returnData.matchCount, 10) / itemsPerPage));
|
||||||
|
|
||||||
if (data.page) {
|
if (data.page) {
|
||||||
var start = Math.max(0, (data.page - 1)) * itemsPerPage;
|
const start = Math.max(0, (data.page - 1)) * itemsPerPage;
|
||||||
metadata.pids = metadata.pids.slice(start, start + itemsPerPage);
|
metadata.pids = metadata.pids.slice(start, start + itemsPerPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
posts.getPostSummaryByPids(metadata.pids, data.uid, {}, next);
|
posts.getPostSummaryByPids(metadata.pids, data.uid, {}, next);
|
||||||
},
|
},
|
||||||
function (posts, next) {
|
function (posts, next) {
|
||||||
|
returnData.posts = posts;
|
||||||
// Append metadata to returned payload (without pids)
|
// Append metadata to returned payload (without pids)
|
||||||
delete metadata.pids;
|
delete metadata.pids;
|
||||||
next(null, Object.assign({
|
next(null, Object.assign(returnData, metadata));
|
||||||
posts: posts,
|
|
||||||
matchCount: matchCount,
|
|
||||||
pageCount: Math.max(1, Math.ceil(parseInt(matchCount, 10) / itemsPerPage)),
|
|
||||||
}, metadata));
|
|
||||||
},
|
},
|
||||||
], callback);
|
], callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterAndSort(pids, data, callback) {
|
function filterAndSort(pids, data, callback) {
|
||||||
|
if (data.sortBy === 'relevance' && !data.replies && !data.timeRange && !data.hasTags) {
|
||||||
|
return setImmediate(callback, null, pids);
|
||||||
|
}
|
||||||
|
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
getMatchedPosts(pids, data, next);
|
getMatchedPosts(pids, data, next);
|
||||||
@@ -135,7 +146,6 @@ function filterAndSort(pids, data, callback) {
|
|||||||
},
|
},
|
||||||
function (result, next) {
|
function (result, next) {
|
||||||
pids = result.posts.map(post => post && post.pid);
|
pids = result.posts.map(post => post && post.pid);
|
||||||
|
|
||||||
next(null, pids);
|
next(null, pids);
|
||||||
},
|
},
|
||||||
], callback);
|
], callback);
|
||||||
@@ -145,7 +155,7 @@ function getMatchedPosts(pids, data, callback) {
|
|||||||
var postFields = ['pid', 'uid', 'tid', 'timestamp', 'deleted', 'upvotes', 'downvotes'];
|
var postFields = ['pid', 'uid', 'tid', 'timestamp', 'deleted', 'upvotes', 'downvotes'];
|
||||||
var categoryFields = [];
|
var categoryFields = [];
|
||||||
|
|
||||||
if (data.sortBy && data.sortBy.startsWith('category.')) {
|
if (data.sortBy.startsWith('category.')) {
|
||||||
categoryFields.push(data.sortBy.split('.')[1]);
|
categoryFields.push(data.sortBy.split('.')[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +171,7 @@ function getMatchedPosts(pids, data, callback) {
|
|||||||
|
|
||||||
async.parallel({
|
async.parallel({
|
||||||
users: function (next) {
|
users: function (next) {
|
||||||
if (data.sortBy && data.sortBy.startsWith('user')) {
|
if (data.sortBy.startsWith('user')) {
|
||||||
uids = _.uniq(postsData.map(post => post.uid));
|
uids = _.uniq(postsData.map(post => post.uid));
|
||||||
user.getUsersFields(uids, ['username'], next);
|
user.getUsersFields(uids, ['username'], next);
|
||||||
} else {
|
} else {
|
||||||
@@ -274,7 +284,7 @@ function filterByTags(posts, hasTags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function sortPosts(posts, data) {
|
function sortPosts(posts, data) {
|
||||||
if (!posts.length || !data.sortBy || data.sortBy === 'relevance') {
|
if (!posts.length || data.sortBy === 'relevance') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,14 +332,14 @@ function getSearchCids(data, callback) {
|
|||||||
if (data.categories.includes('watched')) {
|
if (data.categories.includes('watched')) {
|
||||||
user.getWatchedCategories(data.uid, next);
|
user.getWatchedCategories(data.uid, next);
|
||||||
} else {
|
} else {
|
||||||
next(null, []);
|
setImmediate(next, null, []);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
childrenCids: function (next) {
|
childrenCids: function (next) {
|
||||||
if (data.searchChildren) {
|
if (data.searchChildren) {
|
||||||
getChildrenCids(data.categories, data.uid, next);
|
getChildrenCids(data.categories, data.uid, next);
|
||||||
} else {
|
} else {
|
||||||
next(null, []);
|
setImmediate(next, null, []);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}, next);
|
}, next);
|
||||||
@@ -356,6 +366,6 @@ function getSearchUids(data, callback) {
|
|||||||
if (data.postedBy) {
|
if (data.postedBy) {
|
||||||
user.getUidsByUsernames(Array.isArray(data.postedBy) ? data.postedBy : [data.postedBy], callback);
|
user.getUidsByUsernames(Array.isArray(data.postedBy) ? data.postedBy : [data.postedBy], callback);
|
||||||
} else {
|
} else {
|
||||||
callback(null, []);
|
setImmediate(callback, null, []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -289,10 +289,7 @@ Topics.getMainPids = function (tids, callback) {
|
|||||||
Topics.getTopicsFields(tids, ['mainPid'], next);
|
Topics.getTopicsFields(tids, ['mainPid'], next);
|
||||||
},
|
},
|
||||||
function (topicData, next) {
|
function (topicData, next) {
|
||||||
var mainPids = topicData.map(function (topic) {
|
next(null, topicData.map(topic => topic && topic.mainPid));
|
||||||
return topic && topic.mainPid;
|
|
||||||
});
|
|
||||||
next(null, mainPids);
|
|
||||||
},
|
},
|
||||||
], callback);
|
], callback);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ var async = require('async');
|
|||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
|
||||||
const db = require('../database');
|
const db = require('../database');
|
||||||
|
const user = require('../user');
|
||||||
var privileges = require('../privileges');
|
var privileges = require('../privileges');
|
||||||
var search = require('../search');
|
var search = require('../search');
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ module.exports = function (Topics) {
|
|||||||
function (next) {
|
function (next) {
|
||||||
async.parallel({
|
async.parallel({
|
||||||
tagTids: function (next) {
|
tagTids: function (next) {
|
||||||
getTidsWithSameTags(tid, uid, next);
|
getTidsWithSameTags(tid, next);
|
||||||
},
|
},
|
||||||
searchTids: function (next) {
|
searchTids: function (next) {
|
||||||
getSearchTids(tid, uid, next);
|
getSearchTids(tid, uid, next);
|
||||||
@@ -29,19 +30,26 @@ module.exports = function (Topics) {
|
|||||||
tids = _.shuffle(_.uniq(tids));
|
tids = _.shuffle(_.uniq(tids));
|
||||||
|
|
||||||
if (stop !== -1 && tids.length < stop - start + 1) {
|
if (stop !== -1 && tids.length < stop - start + 1) {
|
||||||
getCategoryTids(tid, uid, next);
|
getCategoryTids(tid, next);
|
||||||
} else {
|
} else {
|
||||||
next(null, []);
|
next(null, []);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
function (categoryTids, next) {
|
function (categoryTids, next) {
|
||||||
tids = _.uniq(tids.concat(categoryTids)).slice(start, stop !== -1 ? stop + 1 : undefined);
|
tids = _.uniq(tids.concat(categoryTids)).slice(start, stop !== -1 ? stop + 1 : undefined);
|
||||||
|
privileges.topics.filterTids('read', tids, uid, next);
|
||||||
|
},
|
||||||
|
function (tids, next) {
|
||||||
Topics.getTopicsByTids(tids, uid, next);
|
Topics.getTopicsByTids(tids, uid, next);
|
||||||
},
|
},
|
||||||
|
function (topics, next) {
|
||||||
|
topics = topics.filter(topic => topic && !topic.deleted && topic.tid !== tid);
|
||||||
|
user.blocks.filter(uid, topics, next);
|
||||||
|
},
|
||||||
], callback);
|
], callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
function getTidsWithSameTags(tid, uid, callback) {
|
function getTidsWithSameTags(tid, callback) {
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
Topics.getTopicTags(tid, next);
|
Topics.getTopicTags(tid, next);
|
||||||
@@ -50,8 +58,7 @@ module.exports = function (Topics) {
|
|||||||
db.getSortedSetRevRange(tags.map(tag => 'tag:' + tag + ':topics'), 0, -1, next);
|
db.getSortedSetRevRange(tags.map(tag => 'tag:' + tag + ':topics'), 0, -1, next);
|
||||||
},
|
},
|
||||||
function (tids, next) {
|
function (tids, next) {
|
||||||
tids = _.uniq(tids).map(Number);
|
next(null, _.uniq(tids).map(Number));
|
||||||
privileges.topics.filterTids('read', tids, uid, next);
|
|
||||||
},
|
},
|
||||||
], callback);
|
], callback);
|
||||||
}
|
}
|
||||||
@@ -68,30 +75,25 @@ module.exports = function (Topics) {
|
|||||||
matchWords: 'any',
|
matchWords: 'any',
|
||||||
categories: [topicData.cid],
|
categories: [topicData.cid],
|
||||||
uid: uid,
|
uid: uid,
|
||||||
page: 1,
|
returnIds: true,
|
||||||
itemsPerPage: 20,
|
|
||||||
}, next);
|
}, next);
|
||||||
},
|
},
|
||||||
function (data, next) {
|
function (data, next) {
|
||||||
var tids = data.posts.map(post => post && post.tid);
|
next(null, _.shuffle(data.tids).slice(0, 20).map(Number));
|
||||||
next(null, tids);
|
|
||||||
},
|
},
|
||||||
], callback);
|
], callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCategoryTids(tid, uid, callback) {
|
function getCategoryTids(tid, callback) {
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
function (next) {
|
function (next) {
|
||||||
Topics.getTopicField(tid, 'cid', next);
|
Topics.getTopicField(tid, 'cid', next);
|
||||||
},
|
},
|
||||||
function (cid, next) {
|
function (cid, next) {
|
||||||
Topics.getRecentTopics(cid, uid, 0, 9, '', next);
|
db.getSortedSetRevRange('cid:' + cid + ':tids:lastposttime', 0, 9, next);
|
||||||
},
|
},
|
||||||
function (data, next) {
|
function (tids, next) {
|
||||||
var tids = data.topics.filter(function (topic) {
|
next(null, tids.map(Number));
|
||||||
return topic && !topic.deleted && tid !== topic.tid;
|
|
||||||
}).map(topic => topic && topic.tid);
|
|
||||||
next(null, tids);
|
|
||||||
},
|
},
|
||||||
], callback);
|
], callback);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user