javorosas
javorosas

Reputation: 769

Mongoose: query full name with regex

I'm using the following code to search a user either by first or last name:

var re = new RegExp(req.params.search, 'i');

User.find()
    .or([{ firstName: re }, { lastName: re }])
    .exec(function(err, users) {
        res.json(JSON.stringify(users));
    });

It works well if search equals 'John' or 'Smith', but not for 'John Sm'.

Any clue how to accomplish this kind of query?

Thanks!

Disclaimer: This question originally appeared on the comments of this previous question 3 years ago and remains unanswered. I'm starting a new thread because 1) It wasn't the main question and 2) I consider this is interesting enough to have its own thread

EDIT:

Suppose the database contains two records: John Smith and John Kennedy.

Upvotes: 3

Views: 4696

Answers (1)

ZeMoon
ZeMoon

Reputation: 20274

Separate the search term by words, and separate them using an alternation operator ('|').

var terms = req.params.search.split(' ');

var regexString = "";

for (var i = 0; i < terms.length; i++)
{
    regexString += terms[i];
    if (i < terms.length - 1) regexString += '|';
}

var re = new RegExp(regexString, 'ig');

For the input 'John Smith', this will create a regex which looks like /John|Smith/ig. This will return true for individual words as well as work when the input is just 'John Sm'

You can play around with this regex to get one more suited to your needs.

EDIT:

The problem here is that your name fields are separate. In this case, applying the same regex to both fields will not result the results that you want. The regex needs to be applied to the same field with the complete name.

A possible solution is using aggregation:

User.aggregate()
    .project({fullName: {$concat: ['$firstName', ' ', '$lastName']}})
    .match({fullName: re})

Upvotes: 12

Related Questions