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.

Hemant Rajpoot
  • 683
  • 1
  • 11
  • 29
  • This post can be a duplicate of another. Check this one: https://stackoverflow.com/questions/15495368/search-in-combination-two-field-in-mongodb – medkhelifi Sep 18 '19 at 07:29

5 Answers5

14

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

Ashh
  • 44,693
  • 14
  • 105
  • 132
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
    ]
  }
})
Cuong Le Ngoc
  • 11,595
  • 2
  • 17
  • 39
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"
            }
        }
   ]
)
nahid
  • 39
  • 3
  • 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"}} – nahid Sep 22 '19 at 04:47
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 });;
  });
},
-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 });
        }
    );
}
imfsilva
  • 139
  • 8
  • 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. – Jacob Lawrence Dec 16 '22 at 07:36