Skip to content

Instantly share code, notes, and snippets.

@jdnichollsc
Last active March 19, 2021 08:10
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jdnichollsc/c4edec104eec3769954b to your computer and use it in GitHub Desktop.
Save jdnichollsc/c4edec104eec3769954b to your computer and use it in GitHub Desktop.
Search users with fullname in MongoDB using Mongoosejs and Aggregation Framework in Node.js
var mongoose = require('mongoose');
var validate = require('mongoose-validator');
var Schema = mongoose.Schema;
var crypto = require('crypto');
var utilities = require('../services/utilities');
var userSchema = new Schema({
firstname: { type : String, trim : true },
lastname: { type : String, trim : true },
username: { type: String, required: true, unique: true, lowercase: true, trim : true, index : true },
password: { type: String, validate: passwordValidator },
email: { type : String, trim : true, validate: emailValidator },
phone: { type : String, trim : true },
address: { type : String, trim : true },
groups: [{ type : Schema.Types.ObjectId, ref : 'Group' }],
created_at: Date,
updated_at: Date
},
{
toObject: { virtuals: true },
toJSON: { virtuals: true }
});
userSchema.virtual('fullname').get(function () {
return [this.firstname, this.lastname].filter(Boolean).join(' ');
});
userSchema.pre('save', function (next) {
if (this.password) {
this.password = encrypt(this.password);
}
utilities.reviewDate(this);
next();
});
function encrypt(text) {
return crypto.createHash("SHA512").update(text).digest("base64");
}
var emailValidator = [
validate({
validator: 'isEmail',
message: 'Please fill a valid email address'
})
];
var passwordValidator = [
validate({
validator: 'isLength',
arguments: [6, 50],
message: 'Password should be between {ARGS[0]} and {ARGS[1]} characters'
}),
validate({
validator: 'matches',
arguments: /\d/,
message: 'Password should contain numbers'
}),
validate({
validator: 'matches',
arguments: /[a-zA-Z]/,
message: 'Password should contain letters'
}),
validate({
validator: 'matches',
arguments: /[A-Z]/,
message: 'Password must contain one uppercase letter'
}),
validate({
validator: 'matches',
arguments: /[\!\@\#\$\%\^\&\*\(\)\_\+\.\,\;\:]/,
message: 'Password should contain a special characters like !@#$%^&*()_+'
})
];
module.exports = mongoose.model('User', userSchema);
var router = express.Router();
var User = require('../models/user');
var authorization = require('../services/authorization'); //Middleware to validate Auth Tokens :)
router.post('/find', authorization.ensureAuthenticated, function (req, res) {
var userName = req.body.search; //userName = 'Juan David Nicholls';
var searchString = new RegExp(userName, 'ig');
User.aggregate()
.project({
fullname: { $concat: ['$firstname', ' ', '$lastname'] },
firstname: 1,
lastname: 1,
username: 1,
email: 1,
phone: 1,
address: 1
})
.match({ fullname: searchString })
.exec(function (err, users) {
if (err) throw err;
res.json({
users: users
});
});
});
var reviewDate = function (instance) {
// get the current date
var currentDate = new Date();
// change the updated_at field to current date
instance.updated_at = currentDate;
// if created_at doesn't exist, add to that field
if (!instance.created_at) {
instance.created_at = currentDate;
}
};
module.exports = {
reviewDate: reviewDate
};
@shepherd1530
Copy link

Can this catch the flip case where the name is passed as lastName + firstName.

@jdnichollsc
Copy link
Author

@shepherd1530 similar to "fullname" you can create another one like this:

reversedname: { $concat: ['$lastname', ' ', '$firstname'] },

and then use an OR conditional from your match method to use both, cheers!

@shepherd1530
Copy link

@shepherd1530 similar to "fullname" you can create another one like this:

reversedname: { $concat: ['$lastname', ' ', '$firstname'] },

and then use an OR conditional from your match method to use both, cheers!

Fix that, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment