Total vote count on topic list
-
@baris can we have another option to calculate the vote numbers of a topic in ACP? So each admin can decide for their forum. I prefer a calculation where all of the positive and negative votes in the thread are considered. Sometimes the first post may not be the key post, but rather it is a question. So it looks 0 vote, although the topic itself is very useful.
-
@crazycells I agree with this. I too have a number of posts on my forum where the initial didn't have many upvotes but subsequent ones do.
-
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.
-
-
thanks @oplik0 and @baris for the plugin...
GitHub - oplik0/nodebb-plugin-total-vote-count: Calculate vote totals based on all posts in topics and not just the inital post
Calculate vote totals based on all posts in topics and not just the inital post - oplik0/nodebb-plugin-total-vote-count
GitHub (github.com)
-
@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, }); }