mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
feat: cache tags:topic:count
This commit is contained in:
@@ -1,16 +1,17 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var async = require('async');
|
const async = require('async');
|
||||||
var validator = require('validator');
|
const validator = require('validator');
|
||||||
|
const _ = require('lodash');
|
||||||
|
|
||||||
var _ = require('lodash');
|
const db = require('../database');
|
||||||
var db = require('../database');
|
const meta = require('../meta');
|
||||||
var meta = require('../meta');
|
const categories = require('../categories');
|
||||||
var categories = require('../categories');
|
const plugins = require('../plugins');
|
||||||
var plugins = require('../plugins');
|
const utils = require('../utils');
|
||||||
var utils = require('../utils');
|
const batch = require('../batch');
|
||||||
var batch = require('../batch');
|
const cache = require('../cache');
|
||||||
|
|
||||||
module.exports = function (Topics) {
|
module.exports = function (Topics) {
|
||||||
Topics.createTags = async function (tags, tid, timestamp) {
|
Topics.createTags = async function (tags, tid, timestamp) {
|
||||||
@@ -53,6 +54,7 @@ module.exports = function (Topics) {
|
|||||||
const isMember = await db.isSortedSetMember('tags:topic:count', tag);
|
const isMember = await db.isSortedSetMember('tags:topic:count', tag);
|
||||||
if (!isMember) {
|
if (!isMember) {
|
||||||
await db.sortedSetAdd('tags:topic:count', 0, tag);
|
await db.sortedSetAdd('tags:topic:count', 0, tag);
|
||||||
|
cache.del('tags:topic:count');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -91,6 +93,7 @@ module.exports = function (Topics) {
|
|||||||
async function updateTagCount(tag) {
|
async function updateTagCount(tag) {
|
||||||
const count = await Topics.getTagTopicCount(tag);
|
const count = await Topics.getTagTopicCount(tag);
|
||||||
await db.sortedSetAdd('tags:topic:count', count || 0, tag);
|
await db.sortedSetAdd('tags:topic:count', count || 0, tag);
|
||||||
|
cache.del('tags:topic:count');
|
||||||
}
|
}
|
||||||
|
|
||||||
Topics.getTagTids = async function (tag, start, stop) {
|
Topics.getTagTids = async function (tag, start, stop) {
|
||||||
@@ -109,6 +112,7 @@ module.exports = function (Topics) {
|
|||||||
const keys = tags.map(tag => 'tag:' + tag + ':topics');
|
const keys = tags.map(tag => 'tag:' + tag + ':topics');
|
||||||
await db.deleteAll(keys);
|
await db.deleteAll(keys);
|
||||||
await db.sortedSetRemove('tags:topic:count', tags);
|
await db.sortedSetRemove('tags:topic:count', tags);
|
||||||
|
cache.del('tags:topic:count');
|
||||||
await db.deleteAll(tags.map(tag => 'tag:' + tag));
|
await db.deleteAll(tags.map(tag => 'tag:' + tag));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -166,7 +170,7 @@ module.exports = function (Topics) {
|
|||||||
const topicTags = await Topics.getTopicsTags(tids);
|
const topicTags = await Topics.getTopicsTags(tids);
|
||||||
const uniqueTopicTags = _.uniq(_.flatten(topicTags));
|
const uniqueTopicTags = _.uniq(_.flatten(topicTags));
|
||||||
|
|
||||||
var tags = uniqueTopicTags.map(tag => ({ value: tag }));
|
const tags = uniqueTopicTags.map(tag => ({ value: tag }));
|
||||||
|
|
||||||
const [tagData, counts] = await Promise.all([
|
const [tagData, counts] = await Promise.all([
|
||||||
Topics.getTagData(tags),
|
Topics.getTagData(tags),
|
||||||
@@ -177,7 +181,7 @@ module.exports = function (Topics) {
|
|||||||
tag.score = counts[index] ? counts[index] : 0;
|
tag.score = counts[index] ? counts[index] : 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
var tagDataMap = _.zipObject(uniqueTopicTags, tagData);
|
const tagDataMap = _.zipObject(uniqueTopicTags, tagData);
|
||||||
|
|
||||||
topicTags.forEach(function (tags, index) {
|
topicTags.forEach(function (tags, index) {
|
||||||
if (Array.isArray(tags)) {
|
if (Array.isArray(tags)) {
|
||||||
@@ -230,6 +234,14 @@ module.exports = function (Topics) {
|
|||||||
return result.matches;
|
return result.matches;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function getAllTags() {
|
||||||
|
const cached = cache.get('tags:topic:count');
|
||||||
|
if (cached !== undefined) {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
return await db.getSortedSetRevRange('tags:topic:count', 0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
async function findMatches(query, cid) {
|
async function findMatches(query, cid) {
|
||||||
let tagWhitelist = [];
|
let tagWhitelist = [];
|
||||||
if (parseInt(cid, 10)) {
|
if (parseInt(cid, 10)) {
|
||||||
@@ -239,13 +251,13 @@ module.exports = function (Topics) {
|
|||||||
if (Array.isArray(tagWhitelist[0]) && tagWhitelist[0].length) {
|
if (Array.isArray(tagWhitelist[0]) && tagWhitelist[0].length) {
|
||||||
tags = tagWhitelist[0];
|
tags = tagWhitelist[0];
|
||||||
} else {
|
} else {
|
||||||
tags = await db.getSortedSetRevRange('tags:topic:count', 0, -1);
|
tags = await getAllTags();
|
||||||
}
|
}
|
||||||
|
|
||||||
query = query.toLowerCase();
|
query = query.toLowerCase();
|
||||||
|
|
||||||
var matches = [];
|
const matches = [];
|
||||||
for (var i = 0; i < tags.length; i += 1) {
|
for (let i = 0; i < tags.length; i += 1) {
|
||||||
if (tags[i].toLowerCase().startsWith(query)) {
|
if (tags[i].toLowerCase().startsWith(query)) {
|
||||||
matches.push(tags[i]);
|
matches.push(tags[i]);
|
||||||
if (matches.length > 19) {
|
if (matches.length > 19) {
|
||||||
@@ -259,7 +271,7 @@ module.exports = function (Topics) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Topics.searchAndLoadTags = async function (data) {
|
Topics.searchAndLoadTags = async function (data) {
|
||||||
var searchResult = {
|
const searchResult = {
|
||||||
tags: [],
|
tags: [],
|
||||||
matchCount: 0,
|
matchCount: 0,
|
||||||
pageCount: 1,
|
pageCount: 1,
|
||||||
@@ -288,15 +300,13 @@ module.exports = function (Topics) {
|
|||||||
return await plugins.fireHook('filter:topic.getRelatedTopics', { topic: topicData, uid: uid });
|
return await plugins.fireHook('filter:topic.getRelatedTopics', { topic: topicData, uid: uid });
|
||||||
}
|
}
|
||||||
|
|
||||||
var maximumTopics = meta.config.maximumRelatedTopics;
|
let maximumTopics = meta.config.maximumRelatedTopics;
|
||||||
if (maximumTopics === 0 || !topicData.tags || !topicData.tags.length) {
|
if (maximumTopics === 0 || !topicData.tags || !topicData.tags.length) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
maximumTopics = maximumTopics || 5;
|
maximumTopics = maximumTopics || 5;
|
||||||
let tids = await async.map(topicData.tags, async function (tag) {
|
let tids = await Promise.all(topicData.tags.map(tag => Topics.getTagTids(tag.value, 0, 5)));
|
||||||
return await Topics.getTagTids(tag.value, 0, 5);
|
|
||||||
});
|
|
||||||
tids = _.shuffle(_.uniq(_.flatten(tids))).slice(0, maximumTopics);
|
tids = _.shuffle(_.uniq(_.flatten(tids))).slice(0, maximumTopics);
|
||||||
const topics = await Topics.getTopics(tids, uid);
|
const topics = await Topics.getTopics(tids, uid);
|
||||||
return topics.filter(t => t && !t.deleted && parseInt(t.uid, 10) !== parseInt(uid, 10));
|
return topics.filter(t => t && !t.deleted && parseInt(t.uid, 10) !== parseInt(uid, 10));
|
||||||
|
|||||||
Reference in New Issue
Block a user