Total vote count on topic list
-
Isn't this how stack overflow works as well? The vote count is for the question itself. I took a look at that code and it wasn't trivial to implement this without a new function so I added that here: https://github.com/NodeBB/NodeBB/pull/11579.
If anyone wants to build it as a plugin it can be done using the function from the above pull request. I will leave the code required here.
In plugin.json add this hook, it gets fired whenever a list of topics is loaded.
{ "hook": "filter:topics.get", "method": "filterTopicsGet" }
Now the code that will recalculate the vote count from the posts of the topics:
const db = require.main.require('./src/database'); library.filterTopicsGet = async (hookData) => { const voteData = await db.getSortedSetsMembersWithScores( hookData.topics.map(t => `tid:${t.tid}:posts:votes`) ); hookData.topics.forEach((t, index) => { if (t) { const allvotes = voteData[index].reduce((acc, cur) => acc + cur.score, 0); t.votes += allvotes; } }); return hookData; };
Now the vote displayed on the topic list will be the total number of votes from all the posts in the topic.
-
-
@crazycells now this is definitely a plugin I'm going to use. Nobody up votes the original topic, but always the individual posts.
-
@phenomlab yeap, we have both cases in the forum, but this calculation makes more sense to us than the first post only.
-
@crazycells said in Total vote count on topic list:
but this calculation makes more sense to us than the first post only.
And for me.
-
@phenomlab I sent a PR to @oplik0 's repro that will change the sorting. https://github.com/oplik0/nodebb-plugin-total-vote-count/pull/19
Just a warning, this will only apply to topics when they receive a new vote on one of their posts. It basically recalculates the new order whenever there is a new vote. Also once this plugin is active uninstalling it will not magically fix the scores to go back to the old sorting. You would need a custom script to fix all the topic votes to set them back to the main post only.
-
thanks a lot @baris
just a quick question, this plugin is not causing any performance issues, right? I am not planning to uninstall it since it is -for us- more correct way to calculate the topic vote counts, but wanted to check since you mentioned some side effects of the plugin after uninstalling it...
-
@baris theoretically, this action will only happen when we try to rank the topics according to votes, right? I mean, if
recently replied
is picked, should this create a performance issue?in our forum, most replied topics have anywhere between 20K-30K posts, not more than that...
-
No the code in the plugin runs whenever you load a list of topics to calculate the votes count displayed. Instead of displaying the normal value it is calculating total votes from each post in the topic. So yeah topics with 30k posts might slow things down but I haven't tested it.
-
@baris my concern at this point is related to performance. Especially if things remain the same even after this specific plugin is disabled or uninstalled.
Will there be an option in the admin console to reset this with the script you previously mentioned?
-
@phenomlab you can run below script in your nodebb folder to reset to the old scores.
/* eslint-disable no-await-in-loop */ /* globals require, console, process */ 'use strict'; const nconf = require('nconf'); nconf.file({ file: 'config.json', }); nconf.defaults({ base_dir: __dirname, views_dir: './build/public/templates', upload_path: 'public/uploads', }); const db = require('./src/database'); db.init(async (err) => { if (err) { console.log(`NodeBB could not connect to your database. Error: ${err.message}`); process.exit(); } await fixVotes(); console.log('done'); process.exit(); }); async function fixVotes() { const batch = require('./src/batch'); await batch.processSortedSet('topics:tid', async (tids) => { let topicData = await db.getObjectsFields( tids.map(tid => `topic:${tid}`), ['tid', 'cid', 'timestamp', 'upvotes', 'downvotes'] ); topicData = topicData.filter(t => t && t.cid); topicData.forEach((t) => { t.votes = parseInt(t.upvotes, 10) - parseInt(t.downvotes, 10); }); await db.sortedSetAddBulk( topicData.map(t => ([`cid:${t.cid}:tids:votes`, t.votes, t.tid])) ); await db.sortedSetAddBulk( topicData.map(t => ([`topic:votes`, t.votes, t.tid])) ); }, { batch: 500, }); }
-
@baris said in Total vote count on topic list:
No the code in the plugin runs whenever you load a list of topics to calculate the votes count displayed. Instead of displaying the normal value it is calculating total votes from each post in the topic. So yeah topics with 30k posts might slow things down but I haven't tested it.
yes, unfortunately, there is a performance issue... there is several seconds of delay while topics are listed...