Hemant Rajpoot
Hemant Rajpoot

Reputation: 690

First Name and Last Name Combine search in mongoDB

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

Answers (5)

Khizar Laique
Khizar Laique

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

nahid
nahid

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

Ashh
Ashh

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

MongoPlayground

Upvotes: 15

imfsilva
imfsilva

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

Cuong Le Ngoc
Cuong Le Ngoc

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

Related Questions