17

I am trying to use the regex with $in operator as mentioned in the docs but I am still unable to get the value.

db.users.find({'profile.firstName':{$in:["/justin/i"]}}).count() = 0

but when I used like this

db.users.find({'profile.firstName':{$in:["justin"]}}).count()=1 and

db.users.find({'profile.firstName':{$in:["Justin"]}}).count()=2

Edited Question

seems like I am not clear with the question I will add the code for easy understanding

I am trying to get the list of documents from a query which is case insensitive.I think it better to explain my doubt with code.

Meteor.users.find({'profile.firstName':{$in:[/justin/i,/helen/i]}}).count()

will give documents whose profile.firstName is justin/Justin/JUSTIn/HElen/helen

but my doubt how to give the variable x=["sai","test","jacob",---etc] in place of helen/justin

2 Answers 2

39

You need to wrap the elements in the array with the RegExp object i.e.

regex = [new RegExp("sai", "i"), new RegExp("test", "i"),...]

You can use the map() method to map the elements in the array with the RegExp wrappers to a new array that you can then use in the regex query with $in:

var x = ["sai","test","jacob","justin"],
    regex = x.map(function (e) { return new RegExp(e, "i"); });

db.users.find({"profile.firstName": { "$in": regex } });

Using $in can be fairly efficient with small arrays but not so well with huge lists since it will skip around in the index to find the matching documents, or walk through the whole collection if there isn't an index to use.


Besides using the $in with the regular expression, you could use a pipe-delimited regex pattern with the keywords list like this:

var x = ["sai","test","jacob","justin"],
    regex = x.join("|");

db.users.find({
    "profile.firstName": {
        "$regex": regex, 
        "$options": "i"
    } 
}).count;
Sign up to request clarification or add additional context in comments.

2 Comments

Both $in and piping the regexs into one worked for me, but the combined regex was 10X faster with an array of 11 regexes and searching a collection of 3.4K documents. Time went from 5000ms to 50ms.
For a left-anchored (starts w/ ^), case-sensitive (no i option) expression, taking the $in approach would use a configured index and thus be optimal, right?
5

try doing this way

db.users.find({'profile.firstName':{$in:[/justin/i]}}).count() = 0

you are passing regex as string.

Usually You should ask one problem at a time so question remains focused to a specific problem

well You can directly pass it, like this

// Here I am creating regex for all the elements in array
let myRegex = new RegExp(myArray.join('|'), i) 
and then I can pass this regex
db.users.find({'profile.firstName':{$in: myRegex}}).count() = 0

3 Comments

Hey thanks for solution but please check question once as I have added a little more to it.
but doesn't that make query with case sensitive
Hahaha Apologize bro, I might have missed the notification, because have been answering quite many question lately

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.