added fuzzy searching and caching
This commit is contained in:
Generated
+14
@@ -15,6 +15,7 @@
|
|||||||
"connect-mongo": "^5.0.0",
|
"connect-mongo": "^5.0.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
|
"fuse.js": "^7.3.0",
|
||||||
"mongoose": "^7.4.1",
|
"mongoose": "^7.4.1",
|
||||||
"multer": "^2.0.2",
|
"multer": "^2.0.2",
|
||||||
"node-schedule": "^2.1.1",
|
"node-schedule": "^2.1.1",
|
||||||
@@ -1950,6 +1951,19 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fuse.js": {
|
||||||
|
"version": "7.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.3.0.tgz",
|
||||||
|
"integrity": "sha512-plz8RVjfcDedTGfVngWH1jmJvBvAwi1v2jecfDerbEnMcmOYUEEwKFTHbNoCiYyzaK2Ws8lABkTCcRSqCY1q4w==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/krisk"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/get-intrinsic": {
|
"node_modules/get-intrinsic": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
"connect-mongo": "^5.0.0",
|
"connect-mongo": "^5.0.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
|
"fuse.js": "^7.3.0",
|
||||||
"mongoose": "^7.4.1",
|
"mongoose": "^7.4.1",
|
||||||
"multer": "^2.0.2",
|
"multer": "^2.0.2",
|
||||||
"node-schedule": "^2.1.1",
|
"node-schedule": "^2.1.1",
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import User, { IUser } from "@/schemas/User";
|
||||||
|
import Fuse, { FuseIndex } from "fuse.js";
|
||||||
|
import { Types } from "mongoose";
|
||||||
|
|
||||||
|
class CachedIndex {
|
||||||
|
private index: FuseIndex = null
|
||||||
|
private list: (IUser & { _id: Types.ObjectId; })[] = null
|
||||||
|
private fuse: Fuse<IUser & { _id: Types.ObjectId; }> = null
|
||||||
|
|
||||||
|
refresh() {
|
||||||
|
this.index = null
|
||||||
|
this.list = null
|
||||||
|
this.fuse = null
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getIndex() {
|
||||||
|
return this.index || (this.index = Fuse.createIndex(['uname', 'fname', 'surname', 'room'], await this.getList()))
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getList() {
|
||||||
|
return this.list || (this.list = await User.find({}, { uname: 1, fname: 1, surname: 1, room: 1 }))
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getFuse(): Promise<typeof this.fuse> {
|
||||||
|
return this.fuse || (this.fuse = new Fuse(await this.getList(), {
|
||||||
|
keys: ['uname', 'fname', 'surname', 'room']
|
||||||
|
}, await this.getIndex()))
|
||||||
|
}
|
||||||
|
|
||||||
|
async search(q: string) {
|
||||||
|
return (await this.getFuse()).search(q, { limit: 5 }).map(r => r.item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new CachedIndex()
|
||||||
@@ -8,9 +8,9 @@ import { notifRouter } from "./notif";
|
|||||||
import { keysRouter } from "./keys";
|
import { keysRouter } from "./keys";
|
||||||
import { cleanRouter } from "./clean";
|
import { cleanRouter } from "./clean";
|
||||||
import { settingsRouter } from "./settings";
|
import { settingsRouter } from "./settings";
|
||||||
import User from "@/schemas/User";
|
|
||||||
import Group from "@/schemas/Group";
|
import Group from "@/schemas/Group";
|
||||||
import usettings from "@/helpers/usettings";
|
import usettings from "@/helpers/usettings";
|
||||||
|
import CachedIndex from "@/helpers/CachedIndex";
|
||||||
|
|
||||||
export const adminRouter = Router()
|
export const adminRouter = Router()
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ adminRouter.use('/clean', cleanRouter)
|
|||||||
adminRouter.use('/settings', settingsRouter)
|
adminRouter.use('/settings', settingsRouter)
|
||||||
|
|
||||||
adminRouter.get('/usearch', async (req, res) => {
|
adminRouter.get('/usearch', async (req, res) => {
|
||||||
var results = await User.find({$text: {$search: req.query['q'].toString()}}, {uname: 1, surname: 1, fname: 1, room: 1})
|
var results = await CachedIndex.search(req.query['q'].toString())
|
||||||
res.send(results)
|
res.send(results)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import CachedIndex from "@/helpers/CachedIndex";
|
||||||
import { Perms, project } from "@/utility";
|
import { Perms, project } from "@/utility";
|
||||||
import mongoose, { Types, Schema } from "mongoose"
|
import mongoose, { Types, Schema } from "mongoose"
|
||||||
|
|
||||||
@@ -29,6 +30,8 @@ const userSchema = new Schema<IUser>({
|
|||||||
|
|
||||||
userSchema.index({uname: "text", room: "text", fname: "text", surname: "text"}, {weights: {fname: 3, surname: 4, room: 2, uname: 1}, default_language: "none"})
|
userSchema.index({uname: "text", room: "text", fname: "text", surname: "text"}, {weights: {fname: 3, surname: 4, room: 2, uname: 1}, default_language: "none"})
|
||||||
|
|
||||||
|
userSchema.post("save", () => {CachedIndex.refresh()})
|
||||||
|
|
||||||
export default mongoose.model("logins", userSchema)
|
export default mongoose.model("logins", userSchema)
|
||||||
|
|
||||||
export function userVisibleFields(user: IUser & {_id: mongoose.Types.ObjectId}): Pick<IUser, "fname" | "surname" | "uname" | "room"> & {_id: mongoose.Types.ObjectId} {
|
export function userVisibleFields(user: IUser & {_id: mongoose.Types.ObjectId}): Pick<IUser, "fname" | "surname" | "uname" | "room"> & {_id: mongoose.Types.ObjectId} {
|
||||||
|
|||||||
Reference in New Issue
Block a user