First Name and Last Name Combine search in mongoDB
Asked Answered
S

5

7

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.

Spartan answered 18/9, 2019 at 7:18 Comment(1)
This post can be a duplicate of another. Check this one: #15495868Weil
I
15

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"
    }
  }
})

MongoPlayground

Indecision answered 18/9, 2019 at 7:38 Comment(4)
very good answer but only issue is its for version 4.2 but I have 4.0 on serverSpartan
@HemantRajpoot You can easily update it to the latest. It will not raise any issue.Indecision
we can't do because of server access,its not our side its client-sideSpartan
life saver answerPipestone
T
3

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
    ]
  }
})
Tessy answered 18/9, 2019 at 7:30 Comment(0)
R
0

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"
            }
        }
   ]
)
Rainier answered 18/9, 2019 at 9:4 Comment(1)
No, because in $match pipeline the query is performing an exact equal operation. But partial-search is also possible. modify $match condition like this $match : { fullname: {$regex: "firstname"}}Rainier
L
0

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 });;
  });
},
Lutetium answered 6/4, 2023 at 7:13 Comment(0)
B
-3

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 });
        }
    );
}
Blueing answered 18/9, 2019 at 7:31 Comment(1)
The scenario is like this. if the user input string is 'Hemant Kumar Rajpoot' but when i search using the string, output will be empty. because the firstname and lastname is stored in two different fields of every documents in the collection. so what we can do is to concat this 2 fields and then perform the search operation to it.Paean

© 2022 - 2024 — McMap. All rights reserved.