Reputation: 690
I have store two field FirstName and LastName stored in MongoDB.from Frontend, I am receiving a string containing both first name and last name separated by space I need a find query which searches both first name & last name combined.
here is eg. scenario
in DB I have following object
{ firstName: "Hemant Kumar", lastName: "Rajpoot" };
if i receive "Hemant Kumar Rajpoot"
it should match.If possible please don't give solution with aggregeation.
Upvotes: 7
Views: 12378
Reputation: 1
Searching from Both Two Fields (First Name & Last Name) in MongoDB prioritising the First Names;
Previously, The Search Results Prioritised the Last Names First, since the search was Alphabetical. Now I've Combined the Results for both but vice versa, (The Intuitive Way).
Can It be Solved Better to be more efficient or optimised, Just a newbie asking.
Suggest me a Better Search Function/Algo if you know. (Please)
globalSearch: function (q, id) {
return new Promise(async (resolve, reject) => {
q = q.toString();
q = q.trim();
var y = q.indexOf(' ') > 0;
var firstParam, secondParam;
var searchQuery, searchQuery1, searchQuery2;
var users = {};
if (y) {
q = q.split(" ");
firstParam = q[0];
secondParam = q[1];
searchQuery = {
is_activated: true,
"privacy.is_profile_public": true,
"privacy.block_list": { $ne: id },
$and: { fname: { "$regex": firstParam, "$options": "i" } }, { lname: { "$regex": secondParam, "$options": "i" } },
}
User.find(searchQuery, function (err, users) {
if (err || !users) {
return reject({
status: 404,
message: "User not found",
});
}
return resolve(users);
},
).sort({ fname: 1 }).collation({ locale: "en", caseLevel: true }).sort({ lname: 1 }).collation({ locale: "en", caseLevel: true });
}
else {
searchQuery1 = {
is_activated: true,
"privacy.is_profile_public": true,
"privacy.block_list": { $ne: id },
fname: { "$regex": q, "$options": "i" },
};
searchQuery2 = {
is_activated: true,
"privacy.is_profile_public": true,
"privacy.block_list": { $ne: id },
lname: { "$regex": q, "$options": "i" },
};
userslist1 = await this.searchCompanion1(searchQuery1);
userslist2 = await this.searchCompanion2(searchQuery2);
users = userslist1 + userslist2
return resolve(users);
}
});
},
searchCompanion1: function (Q) {
return new Promise((resolve, reject) => {
User.find(Q, function (err, users) {
if (err || !users) {
console.log(err);
}
return resolve(users);
},
).sort({ fname: 1 }).collation({ locale: "en", caseLevel: true }).sort({ lname: 1 }).collation({ locale: "en", caseLevel: true });;
});
},
searchCompanion2: function (Q) {
return new Promise((resolve, reject) => {
User.find(Q, function (err, users) {
if (err || !users) {
console.log(err);
}
return resolve(users);
},
).sort({ fname: 1 }).collation({ locale: "en", caseLevel: true }).sort({ lname: 1 }).collation({ locale: "en", caseLevel: true });;
});
},
Upvotes: 0
Reputation: 39
If you would like to do it using aggregation. here is an example
db.user.aggregate(
[
{
$project : {
fullname: {$concat: ["$firstname", " ", "$lastname"]}
},
},
{
$match : {
fullname: "your full name"
}
}
]
)
Upvotes: 0
Reputation: 46461
You can use $regexMatch
if you are using latest mongodb version 4.2
db.collection.find({
"$expr": {
"$regexMatch": {
"input": { "$concat": ["$first", " ", "$last"] },
"regex": "a", //Your text search here
"options": "i"
}
}
})
Upvotes: 15
Reputation: 139
It's as simple as checking if the fields entered (firstname
, lastname
) matches any user in the database.
module.exports.checkFullName = (req, res, next) => {
myCollection.findOne({ firstName: req.firstname, lastName: req.lastname },
(err, user) => {
if (!user)
return res.status(404).json({ status: false, message: 'User not found' });
else
return res.status(200).json({ status: true, user });
}
);
}
Upvotes: -3
Reputation: 11975
You can do it with combination of $expr, $eq and $concat.
Example:
db.yourCollection.find({
$expr: {
$eq: [
{$concat: ["$firstName", " ", "$lastName"]},
"Hemant Kumar Rajpoot" // your full name to search here
]
}
})
Upvotes: 3