mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
refactor: remove cid👎tids (and variants) from intersection in /world, fixes #13125
- remove "poor man's intersect" but not considering the main `cid👎tids` set at all
including its variants (voting, reply time, etc.)
- added a new method Categories.sortTidsBySet which allows after-the-fact sorting
of tids by their score in a set.
This commit is contained in:
@@ -99,7 +99,8 @@ module.exports = function (Categories) {
|
||||
most_views: `cid:${cid}:tids:views`,
|
||||
};
|
||||
|
||||
const set = new Set([sortToSet.hasOwnProperty(sort) ? sortToSet[sort] : `cid:${cid}:tids`]);
|
||||
const mainSet = sortToSet.hasOwnProperty(sort) ? sortToSet[sort] : `cid:${cid}:tids`;
|
||||
const set = new Set([mainSet]);
|
||||
|
||||
if (data.tag) {
|
||||
if (Array.isArray(data.tag)) {
|
||||
@@ -116,6 +117,7 @@ module.exports = function (Categories) {
|
||||
}
|
||||
|
||||
if (parseInt(cid, 10) === -1 && uid > 0) {
|
||||
set.delete(mainSet);
|
||||
set.add(`uid:${uid}:inbox`);
|
||||
}
|
||||
const setValue = Array.from(set);
|
||||
@@ -251,4 +253,24 @@ module.exports = function (Categories) {
|
||||
});
|
||||
notifications.push(notification, followers);
|
||||
};
|
||||
|
||||
Categories.sortTidsBySet = async (tids, cid, sort) => {
|
||||
sort = sort || meta.config.categoryTopicSort || 'recently_replied';
|
||||
const sortToSet = {
|
||||
recently_replied: `cid:${cid}:tids`,
|
||||
recently_created: `cid:${cid}:tids:create`,
|
||||
most_posts: `cid:${cid}:tids:posts`,
|
||||
most_votes: `cid:${cid}:tids:votes`,
|
||||
most_views: `cid:${cid}:tids:views`,
|
||||
};
|
||||
|
||||
const orderBy = sortToSet[sort];
|
||||
const scores = await db.sortedSetScores(orderBy, tids);
|
||||
const sorted = tids
|
||||
.map((tid, idx) => [tid, scores[idx]])
|
||||
.sort(([, a], [, b]) => b - a)
|
||||
.map(([tid]) => tid);
|
||||
|
||||
return sorted;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -20,22 +20,6 @@ const validSorts = [
|
||||
'recently_replied', 'recently_created', 'most_posts', 'most_votes', 'most_views',
|
||||
];
|
||||
|
||||
async function getTids(data) {
|
||||
// Poor man's intersect used instead of getSortedSetIntersect because the zsets are huge
|
||||
const sets = await categories.buildTopicsSortedSet(data);
|
||||
const intersect = Array.isArray(sets);
|
||||
const mainSet = intersect ? sets.shift() : sets;
|
||||
let tids = await db.getSortedSetRevRange(mainSet, 0, 499);
|
||||
if (!intersect) {
|
||||
return tids.slice(data.start, data.stop + 1);
|
||||
}
|
||||
|
||||
let intersection = await Promise.all(sets.map(async set => db.isSortedSetMembers(set, tids)));
|
||||
intersection = intersection.reduce((memo, cur) => memo.map((show, idx) => show && cur[idx]));
|
||||
tids = tids.filter((_, idx) => intersection[idx]);
|
||||
return tids.slice(data.start, data.stop + 1);
|
||||
}
|
||||
|
||||
controller.list = async function (req, res) {
|
||||
if (!req.uid) {
|
||||
return helpers.redirect(res, '/recent?cid=-1', false);
|
||||
@@ -69,7 +53,8 @@ controller.list = async function (req, res) {
|
||||
data.name = '[[world:name]]';
|
||||
delete data.children;
|
||||
|
||||
const tids = await getTids(cidQuery);
|
||||
let tids = await categories.getTopicIds(cidQuery);
|
||||
tids = await categories.sortTidsBySet(tids, -1, sort); // sorting not handled if cid is -1
|
||||
data.topicCount = tids.length;
|
||||
data.topics = await topics.getTopicsByTids(tids, { uid: req.uid });
|
||||
topics.calculateTopicIndices(data.topics, start);
|
||||
|
||||
Reference in New Issue
Block a user