-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: ability to search categories, #8813
- Loading branch information
1 parent
faeb637
commit 34c42c6
Showing
6 changed files
with
117 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
'use strict'; | ||
|
||
const _ = require('lodash'); | ||
|
||
const privileges = require('../privileges'); | ||
const plugins = require('../plugins'); | ||
const db = require('../database'); | ||
|
||
module.exports = function (Categories) { | ||
Categories.search = async function (data) { | ||
const query = data.query || ''; | ||
const page = data.page || 1; | ||
const uid = data.uid || 0; | ||
const paginate = data.hasOwnProperty('paginate') ? data.paginate : true; | ||
|
||
const startTime = process.hrtime(); | ||
|
||
let cids = await findCids(query, data.hardCap); | ||
|
||
const result = await plugins.hooks.fire('filter:categories.search', { | ||
cids: cids, | ||
uid: uid, | ||
}); | ||
cids = await privileges.categories.filterCids('find', result.cids, uid); | ||
|
||
const searchResult = { | ||
matchCount: cids.length, | ||
}; | ||
|
||
if (paginate) { | ||
const resultsPerPage = data.resultsPerPage || 50; | ||
const start = Math.max(0, page - 1) * resultsPerPage; | ||
const stop = start + resultsPerPage; | ||
searchResult.pageCount = Math.ceil(cids.length / resultsPerPage); | ||
cids = cids.slice(start, stop); | ||
} | ||
|
||
const childrenCids = await getChildrenCids(cids, uid); | ||
const uniqCids = _.uniq(cids.concat(childrenCids)); | ||
const categoryData = await Categories.getCategories(uniqCids, uid); | ||
|
||
Categories.getTree(categoryData, 0); | ||
await Categories.getRecentTopicReplies(categoryData, uid, data.qs); | ||
categoryData.sort(function (c1, c2) { | ||
if (c1.parentCid !== c2.parentCid) { | ||
return c1.parentCid - c2.parentCid; | ||
} | ||
return c1.order - c2.order; | ||
}); | ||
searchResult.timing = (process.elapsedTimeSince(startTime) / 1000).toFixed(2); | ||
searchResult.categories = categoryData.filter(c => cids.includes(c.cid)); | ||
return searchResult; | ||
}; | ||
|
||
async function findCids(query, hardCap) { | ||
if (!query || String(query).length < 2) { | ||
return []; | ||
} | ||
const data = await db.getSortedSetScan({ | ||
key: 'categories:name', | ||
match: '*' + String(query).toLowerCase() + '*', | ||
limit: hardCap || 500, | ||
}); | ||
return data.map(data => parseInt(data.split(':').pop(), 10)); | ||
} | ||
|
||
async function getChildrenCids(cids, uid) { | ||
const childrenCids = await Promise.all(cids.map(cid => Categories.getChildrenCids(cid))); | ||
return await privileges.categories.filterCids('find', childrenCids.flat(), uid); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
'use strict'; | ||
|
||
const db = require('../../database'); | ||
const batch = require('../../batch'); | ||
|
||
module.exports = { | ||
name: 'Create category name sorted set', | ||
timestamp: Date.UTC(2021, 0, 27), | ||
method: async function () { | ||
const progress = this.progress; | ||
|
||
await batch.processSortedSet('categories:cid', async function (cids) { | ||
const keys = cids.map(cid => 'category:' + cid); | ||
let categoryData = await db.getObjectsFields(keys, ['cid', 'name']); | ||
categoryData = categoryData.filter(c => c.cid && c.name); | ||
const bulkAdd = categoryData.map(function (cat) { | ||
return [ | ||
'categories:name', | ||
0, | ||
String(cat.name).substr(0, 200).toLowerCase() + ':' + cat.cid, | ||
]; | ||
}); | ||
await db.sortedSetAddBulk(bulkAdd); | ||
progress.incr(cids.length); | ||
}, { | ||
batch: 500, | ||
progress: progress, | ||
}); | ||
}, | ||
}; |