Skip to content

Commit e5864af

Browse files
committed
implement fuzzy search
1 parent 13a1836 commit e5864af

7 files changed

Lines changed: 202 additions & 283 deletions

File tree

api/main_endpoints/models/User.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const mongoose = require('mongoose');
2+
const mongooseFuzzySearching = require('mongoose-fuzzy-searching');
23
const Schema = mongoose.Schema;
34
const bcrypt = require('bcryptjs');
45
const membershipState = require('../../util/constants').MEMBERSHIP_STATE;
@@ -78,6 +79,10 @@ const UserSchema = new Schema(
7879
{ collection: 'User' }
7980
);
8081

82+
UserSchema.plugin(mongooseFuzzySearching, {
83+
fields: ['firstName', 'lastName', 'email'],
84+
});
85+
8186
UserSchema.pre('save', function(next) {
8287
const member = this;
8388
let emailRegExp = new RegExp(['^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0',

api/main_endpoints/routes/ShortcutSearch.js

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,34 +19,14 @@ const logger = require('../../util/logger');
1919
router.post('/', async function(req, res) {
2020
if (!checkIfTokenSent(req)) {
2121
return res.sendStatus(FORBIDDEN);
22-
} else if (!checkIfTokenValid(req, membershipState.OFFICER)) {
22+
} else if (!checkIfTokenValid(req)) {
2323
return res.sendStatus(UNAUTHORIZED);
2424
}
2525

2626
if (!req.body.query) {
2727
return res.status(OK).send({ items: [] });
2828
}
2929

30-
const query = req.body.query.replace(/[*\s]/g, '');
31-
32-
// Create a fuzzy regex pattern to match characters in order, e.g., "pone" -> /p.*o.*n.*e/i
33-
const fuzzyPattern = query.split('').join('.*');
34-
const pattern = new RegExp(fuzzyPattern, 'i');
35-
36-
const maybeOr = {
37-
$or: [
38-
{
39-
$expr: {
40-
$regexMatch: {
41-
input: { $concat: ['$firstName', '$lastName'] },
42-
regex: pattern,
43-
}
44-
}
45-
},
46-
{ email: { $regex: new RegExp(query, 'i')} }
47-
]
48-
};
49-
5030
/**
5131
* Function to calculate scores based on token matches for sorting
5232
* @param {string} str - The string to score against
@@ -94,17 +74,21 @@ router.post('/', async function(req, res) {
9474
};
9575
};
9676

97-
// Find user and sort results based on best match of full name or email
98-
User.find(maybeOr, { password: 0 })
99-
.limit(5)
100-
.then(items => {
101-
items.sort(sortByMatch(req.body.query));
102-
res.status(OK).send({ items });
103-
})
104-
.catch((error) => {
105-
logger.error('/shortcutsearchusers encountered an error:', error);
106-
res.sendStatus(BAD_REQUEST);
107-
});
77+
try {
78+
const users = await User.find({});
79+
for (const user of users) {
80+
await user.save();
81+
}
82+
const topUsers = await User.fuzzySearch(req.body.query)
83+
.limit(5)
84+
.select('-password, -apiKey');
85+
86+
const sortUsers = topUsers.sort(sortByMatch(req.body.query));
87+
88+
return res.status(OK).send({ items: sortUsers });
89+
} catch (e) {
90+
return res.sendStatus(SERVER_ERROR);
91+
}
10892
});
10993

11094
module.exports = router;

0 commit comments

Comments
 (0)