37

I would like to make query MongoDB for documents based on a regex expression that I contruct. For e.g I have constructed a simple regex as follows that is a combination of a random letter and a random number for in Nodejs

var randnum = Math.floor((Math.random() * 10) + 1);
var alpha = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','X','Y','Z'];
var randletter = alpha[Math.floor(Math.random() * alpha.length)];
var val = randletter + randnum + '.*;

I have tried various combinations for the regex variable like

var stream = collection.find({"FirstName": /val/).stream();
&&
var stream = collection.find({"FirstName": /$val/).stream();
&&
var stream = collection.find({"FirstName": {$in : [{$regex:val}]}}).stream()
&&
var stream = collection.find({"FirstName": {$in : [{$regex:$val}]}}).stream()

None o it seem to work. However when I write the actual regex I get the records for e.g.

var stream = collection.find({"FirstName": /J.*/).stream();

Any help will be appreciated.

Thanks Ganesh

2
  • Wizard, Thanks. However, this did not seem to work.var stream = collection.find({"FirstName": {$regex:val}}).stream(); stream.on("data", function(item) results.push(item); Commented Nov 2, 2014 at 15:03
  • Any error occurs, or just doesn't get the expected result? Example of a document stored in the database may be helpful. Commented Nov 2, 2014 at 15:14

7 Answers 7

58

I was having same problem with my title and after lots of searching, i found this answer Here,

var search = 'Joe';
db.users.find(name: /^search/)
db.users.find(name: {$regex: /^search/});
db.users.find(name: {$regex: "/^" + search + "/"});

The queries above won’t return anything. The solution to this little problem is quite simple:

db.users.find(name: new RegExp(search)) //For substring search, case sensitive. 
db.users.find(name: new RegExp('^' + search + '$')) //For exact search, case sensitive
db.users.find(name: new RegExp(search, ‘i')) //For substring search, case insensitive
db.users.find(name: new RegExp('^' +search + '$', 'i')); //For exact search, case insensitive

Other flags or properties can be added base on reference here

Sign up to request clarification or add additional context in comments.

5 Comments

db.users.find(name: {$regex: "/^" + search + "/"}); exactly what I needed
For me it didn't work using the /. Like in this example: var name = '.*'+user.name+'.*' found = db.users.findOne({ 'name': {$regex: name} })
i was exactly looking for db.users.find(name: new RegExp('^' +search + '$', 'i')); thanks..
Hamza : I am facing an issue with case insensitive and exact search . The rule I have added is as follows {name: new RegExp('^' + search + '$' , "i")} . The prolem is that when I search test... (with dots, which I need since there is entry with dots) , I got results test123, test333 etc.... How can I get only entry test...
It's not working with MongoDB. It's passing "search" as a string as supposed to value of the variable.
49

You need to create a regular expression object from the string using the RegExp constructor as the /.../ syntax is only for use with literals.

var stream = collection.find({"FirstName": new RegExp(val)}).stream();

3 Comments

JohnnyHK - That worked awfully well. The changes I made were var val = randletter + ".*" + randnum + ".*"; var stream = collection.find({"FirstName": new RegExp(val)}).stream(); Thanks Ganesh
I have tried what you suggested, but it didn't seem to work. What I have to do is, let pattern = '/^\/'+ cat + '/'; col.find({name: new RegExp(pattern)}) where cat is a variable whose value I am concatenating to create pattern for matching.
Remove the / characters from pattern and it will work. @AvaniKhabiya
11

Use the following code to use dynamic value in regex with or operations

{$match: { $or: [{ 'title': { $regex:  request.query.val, $options: 'i'} }, { 'skills_required': { $regex:  request.query.val, $options: 'i'} }] }},

1 Comment

$or: [{users: { $elemMatch: { name: { $regex: ${filters.userName}, $options: 'i' } } },}]; . . .. . . .great answer! also works with string interpolation e.g.
10

If you want to use the variable val as a parameter of the query part, you can use $regex, for example:

collection.find({"FirstName": {$regex:val}})

It is not allowed to put $regex in $in operator according to the manual.

If you want to put regular expression object in $in operator, you have to use JavaScript regular expression object, for example:

collection.find({"FirstName": {$in: [/abc/, /123/]}})

By the way, val in /val/ is constant string, not the variable as you defined above.

4 Comments

Hi -Thanks. But it did not work - var val = randletter + randnum + '.*'; var stream = collection.find({"FirstName": {$regex:val}}).stream(); Regards Ganesh
@TinniamV.Ganesh, What's value of FirstName in database? Or maybe just no items can satisfy your query needs?
Wizard - Firstname is just a string of letters and numbers. I tried it a couple of times it always returned an empty set. The other version var stream = collection.find({"FirstName": new RegExp(val)}).stream(); worked. Thanks anyway. Regards Ganesh
@TinniamV.Ganesh, Thanks for the reply. I think I missed some details about your circumstances which do not support $regex.
8

If your regex includes a variable, make sure to escape it.

function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

This can be used like this

new RegExp(escapeRegExp(searchString), 'i')

Or in a mongoDb query like this

{ '$regex': escapeRegExp(searchString) }

Posted same comment here

Comments

3
let test = `what your regex should search`;

collection.find({
    fieldName: {$regex: test}
}).then(result => red.send(result));

// tested on mongoose but should work on mongodb too

Comments

0

My use case was to fetch results STARTS WITH a given query, and below solution worked for me.

let q = '^' + query;
return await User.find({ name: { $regex: q, $options: 'i' } }).select('name').limit(10);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.