394

Example:

> db.stuff.save({"foo":"bar"});

> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0
John Saunders
  • 160,644
  • 26
  • 247
  • 397
Luke Dennis
  • 14,212
  • 17
  • 56
  • 69
  • 5
    Since MongoDB 3.2 you can execute case-insensitive search with `$caseSensitive: false`. See: https://docs.mongodb.org/manual/reference/operator/query/text/#op._S_text – martin Apr 04 '16 at 08:21
  • 5
    Note that that is on text indexes only. – Willem D'Haeseleer Aug 16 '16 at 15:40
  • 3
    @martin: `$caseSensitive` is false already by default, and that doesn't answer the question, because it only works on indexed fields. OP was looking for case-insensitive string comparison. – Dan Dascalescu May 12 '19 at 22:49
  • Best option I to find duplicates: https://stackoverflow.com/questions/40978162/mongodb-find-all-lower-uppercase-duplicates-in-db – I.G. Pascual Oct 18 '20 at 09:45

27 Answers27

438

You could use a regex.

In your example that would be:

db.stuff.find( { foo: /^bar$/i } );

I must say, though, maybe you could just downcase (or upcase) the value on the way in rather than incurring the extra cost every time you find it. Obviously this wont work for people's names and such, but maybe use-cases like tags.

rfunduk
  • 30,053
  • 5
  • 59
  • 54
  • 31
    This works perfectly. Got it working in PHP with: $collection->find(array('key' => new MongoRegex('/'.$val.'/i'))); – Luke Dennis Dec 09 '09 at 04:22
  • 2
    Especially if you're interpolating a string ({foo: /#{x}/i}) that could have a question mark in it.. – Peter Ehrlich Dec 16 '11 at 18:53
  • Don't forget to add preg_quote() – user956584 Feb 25 '12 at 02:40
  • 20
    Dont forget also ^and $ : MongoRegex('/^' . preg_quote($val) . '$/i') – Julien Jan 01 '13 at 20:26
  • 29
    Note that this will do a fullscan instead of using index. – Martin Konicek Apr 25 '13 at 13:29
  • 15
    it won't do a fullscan if he uses the ^ anchor at the beginning, hence the importance of Julien's advice. – Pax Jul 06 '13 at 22:37
  • Hey All, I'd followed JULIEN. But, couldn't get the result. After that, I've followed LUKE DENNIS. I got the results. Please advice me. Which one is technically right? – user2003356 Oct 30 '13 at 05:24
  • it works for me thanks. and yes, pre down/up case on the fly is really good suggestion. – spiritwalker Jan 05 '14 at 23:52
  • I had to do: array( 'key' => array( '$regex' => new MongoRegex('/^' . $val . '$/i'))); – Skunkwaffle Jul 07 '14 at 16:55
  • I don't see how lowercasing/uppercasing the string would help. If the value in the DB is "FoO" and you are searching for either "foo" or "FOO," neither will match. It's not like traditional SQL where you have the DB field in a variable and you can lowercase both the search string and DB string. Am I missing something obvious? – CaptSaltyJack May 06 '15 at 16:18
  • They mean to lowercase the value stored on the db ( "foo" instead of "FoO") - not the query. This would probably require the addition of a special "search" value in the doc: { "myvalue" : "FoO", "searchable" : "foo" } – noderman Dec 02 '15 at 19:55
  • 1
    This approach does not works if you try to check string which contains regex-related characters. For example question mark or asterisk. – Alex G.P. Dec 23 '15 at 21:02
  • @AlexG.P. you can simply escape those characters as usual. `/this\/has\/slashes\//` – rfunduk Feb 09 '16 at 16:24
  • 5
    "For case insensitive regular expression queries, these queries generally cannot use indexes effectively." -> https://docs.mongodb.com/manual/reference/operator/query/regex/ – sebpiq Apr 28 '17 at 11:26
  • 2
    Regex works, but they scan the whole database applying regex and don't uses indexes. What is highly inneficient – Gustavo Garcia Feb 14 '18 at 22:41
  • 1
    Starting with MongoDB 3.4, there's a much faster and more appropriate solution: [Case Insensitive Indexes](https://stackoverflow.com/questions/1863399/mongodb-is-it-possible-to-make-a-case-insensitive-query/40914924#40914924). Also @Pax, that's incorrect. See the reference posted by *sebpiq*. – Dan Dascalescu May 13 '19 at 06:52
  • 1
    @rfunduk It will not work if string contains special character as these characters has special meaning in regex. – Pulkit Aggarwal Aug 05 '20 at 09:04
210

UPDATE:

The original answer is now obsolete. Mongodb now supports advanced full text searching, with many features.

ORIGINAL ANSWER:

It should be noted that searching with regex's case insensitive /i means that mongodb cannot search by index, so queries against large datasets can take a long time.

Even with small datasets, it's not very efficient. You take a far bigger cpu hit than your query warrants, which could become an issue if you are trying to achieve scale.

As an alternative, you can store an uppercase copy and search against that. For instance, I have a User table that has a username which is mixed case, but the id is an uppercase copy of the username. This ensures case-sensitive duplication is impossible (having both "Foo" and "foo" will not be allowed), and I can search by id = username.toUpperCase() to get a case-insensitive search for username.

If your field is large, such as a message body, duplicating data is probably not a good option. I believe using an extraneous indexer like Apache Lucene is the best option in that case.

Jhuliano Moreno
  • 929
  • 8
  • 23
Dan
  • 2,733
  • 1
  • 17
  • 6
  • Any documentation available that show how the indexes work? I'm asking because, if I recall, marklogic is able to hold an additional case insensitive index... maybe mongo does the same thing? – RayLoveless Dec 31 '12 at 17:05
  • Raymo, a case insensitive index feature does not exist today in Mongo, but it's being talked about. https://jira.mongodb.org/browse/SERVER-90 – Dan Feb 19 '13 at 03:18
  • @Dan, it should be noted, that the fancy new full text index has it's problems - "For the Latin alphabet, text indexes are case insensitive for non-diacritics; i.e. case insensitive for [A-z]. For all other characters, text indexes treat them as distinct."; So, for non Latin alphabet, it might be reasonable to use regex search which should also take an advantage of existing index (see my comment above). – Sergiy Sokolenko Nov 16 '15 at 13:32
  • 1
    I recently tested with mongodb 3.0.4 with 100,000 records with a name field indexed. The case insensitive regex query takes over 200ms where casesensitive regex takes about 16ms.(Both cases include regex start with '^') – dCoder Dec 06 '15 at 07:44
  • 2
    Docs have been updated maybe. They now say "For case sensitive regular expression queries, if an index exists for the field, then MongoDB matches the regular expression against the values in the index, which can be faster than a collection scan." – Jeff Lewis Aug 25 '16 at 22:24
  • 3
    Another limitation with text index is you can only have one per collection (multiple columns), so doesn't suit if you need to isolate searches on different fields for different cases. – Paul Grimshaw Apr 28 '17 at 16:43
  • That's cool and all, but stackoverflow answers are not expecting a 20-page link dump. Toss up a TL;DR? Indexes also don't seem relevant to what OP is asking for. – dylanh724 May 17 '18 at 16:20
  • Note that it's index based, and it mean in aggregation framework, it only support first layer of pipeline (and maybe second depend on the pipes), and it's unusable in other layers. – Hassan Faghihi Apr 28 '19 at 04:47
  • 3
    @SergiySokolenko: the docs now say (last paragraph in [the section](https://docs.mongodb.com/manual/reference/operator/query/regex/#index-use)): "Case insensitive regular expression queries generally cannot use indexes effectively. The $regex implementation is not collation-aware and is unable to utilize case-insensitive indexes." – Dan Dascalescu May 13 '19 at 05:27
  • 3
    Using full-text search is wrong in this case (and potentially *dangerous*), because the question was about making a case-insensitive query, e.g. `username: 'bill'` matching `BILL` or `Bill`, not a full-text search query, which would also match [stemmed words](https://docs.mongodb.com/manual/reference/operator/query/text/index.html#stemmed-words) of `bill`, such as `Bills`, `billed` etc. – Dan Dascalescu May 13 '19 at 05:32
151

Starting with MongoDB 3.4, the recommended way to perform fast case-insensitive searches is to use a Case Insensitive Index.

I personally emailed one of the founders to please get this working, and he made it happen! It was an issue on JIRA since 2009, and many have requested the feature. Here's how it works:

A case-insensitive index is made by specifying a collation with a strength of either 1 or 2. You can create a case-insensitive index like this:

db.cities.createIndex(
  { city: 1 },
  { 
    collation: {
      locale: 'en',
      strength: 2
    }
  }
);

You can also specify a default collation per collection when you create them:

db.createCollection('cities', { collation: { locale: 'en', strength: 2 } } );

In either case, in order to use the case-insensitive index, you need to specify the same collation in the find operation that was used when creating the index or the collection:

db.cities.find(
  { city: 'new york' }
).collation(
  { locale: 'en', strength: 2 }
);

This will return "New York", "new york", "New york" etc.

Other notes

  • The answers suggesting to use full-text search are wrong in this case (and potentially dangerous). The question was about making a case-insensitive query, e.g. username: 'bill' matching BILL or Bill, not a full-text search query, which would also match stemmed words of bill, such as Bills, billed etc.

  • The answers suggesting to use regular expressions are slow, because even with indexes, the documentation states:

    "Case insensitive regular expression queries generally cannot use indexes effectively. The $regex implementation is not collation-aware and is unable to utilize case-insensitive indexes."

    $regex answers also run the risk of user input injection.

Community
  • 1
  • 1
user3413723
  • 11,147
  • 6
  • 55
  • 64
  • I cannot seem to find any way to add a default collation to a collection once it has been created. Is there any way to do so? – IncrediblePony Jun 03 '20 at 12:41
  • How to go about using findOne().collation? findOne() does not seem to have it like find() does? – Meryan May 11 '22 at 04:05
  • It's worth noting that this does not work with MongoDB Realm. https://www.mongodb.com/community/forums/t/collation-is-not-a-function/120679/2 – Timothee W Aug 15 '22 at 02:04
93

If you need to create the regexp from a variable, this is a much better way to do it: https://stackoverflow.com/a/10728069/309514

You can then do something like:

var string = "SomeStringToFind";
var regex = new RegExp(["^", string, "$"].join(""), "i");
// Creates a regex of: /^SomeStringToFind$/i
db.stuff.find( { foo: regex } );

This has the benefit be being more programmatic or you can get a performance boost by compiling it ahead of time if you're reusing it a lot.

Community
  • 1
  • 1
Fotios
  • 3,643
  • 1
  • 28
  • 30
  • 1
    `new RegExp("^" + req.params.term.toLowerCase(), "i") ` also works fine – Tahir Yasin Mar 29 '17 at 15:43
  • 7
    you should consider escaping the string for increasing security if the variable comes from a request: https://stackoverflow.com/a/50633536/5195127 – David Ortiz May 31 '18 at 22:19
  • Starting with MongoDB 3.4, there is native support for [Case Insensitive Indexes](https://stackoverflow.com/questions/1863399/mongodb-is-it-possible-to-make-a-case-insensitive-query/40914924#40914924) – Dan Dascalescu May 13 '19 at 06:59
75

Keep in mind that the previous example:

db.stuff.find( { foo: /bar/i } );

will cause every entries containing bar to match the query ( bar1, barxyz, openbar ), it could be very dangerous for a username search on a auth function ...

You may need to make it match only the search term by using the appropriate regexp syntax as:

db.stuff.find( { foo: /^bar$/i } );

See http://www.regular-expressions.info/ for syntax help on regular expressions

jflaflamme
  • 1,767
  • 12
  • 9
43
db.company_profile.find({ "companyName" : { "$regex" : "Nilesh" , "$options" : "i"}});
Nilesh
  • 2,054
  • 3
  • 23
  • 43
  • 4
    Have you looked at the existing answers before posting this one? Instead of a quasi-duplicate code-only answer, you might want to explain how it add something of value compared to the previous answers. – Dan Dascalescu May 12 '19 at 22:56
  • 1
    I just want to add that this answer is what got me to a solution. I'm using a PHP framework and this fit into the ORM syntax well while the other solutions here didn't. `$existing = Users::masterFind('all', ['conditions' => ['traits.0.email' => ['$regex' => "^$value$", '$options' => 'i']]]);` – Don Rzeszut Sep 12 '19 at 17:41
  • 2
    Just want to reiterate that using $regex like this will cause a collection scan especially when you use "^...$". The full explanation can be found on Mongo link [here](https://docs.mongodb.com/manual/reference/operator/query/regex/#index-use). As your collection grows, the performance will be impacted significantly. – InitialV Aug 20 '20 at 03:05
23
db.zipcodes.find({city : "NEW YORK"}); // Case-sensitive
db.zipcodes.find({city : /NEW york/i}); // Note the 'i' flag for case-insensitivity
Bas Peeters
  • 3,269
  • 4
  • 33
  • 49
rshivamca
  • 249
  • 2
  • 2
22

TL;DR

Correct way to do this in mongo

Do not Use RegExp

Go natural And use mongodb's inbuilt indexing , search

Step 1 :

db.articles.insert(
   [
     { _id: 1, subject: "coffee", author: "xyz", views: 50 },
     { _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 },
     { _id: 3, subject: "Baking a cake", author: "abc", views: 90  },
     { _id: 4, subject: "baking", author: "xyz", views: 100 },
     { _id: 5, subject: "Café Con Leche", author: "abc", views: 200 },
     { _id: 6, subject: "Сырники", author: "jkl", views: 80 },
     { _id: 7, subject: "coffee and cream", author: "efg", views: 10 },
     { _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 }
   ]
)
 

Step 2 :

Need to create index on whichever TEXT field you want to search , without indexing query will be extremely slow

db.articles.createIndex( { subject: "text" } )

step 3 :

db.articles.find( { $text: { $search: "coffee",$caseSensitive :true } } )  //FOR SENSITIVITY
db.articles.find( { $text: { $search: "coffee",$caseSensitive :false } } ) //FOR INSENSITIVITY


 
Community
  • 1
  • 1
vijay
  • 10,276
  • 11
  • 64
  • 79
  • 1
    Good option, but there's nothing more "correct" about using a text index versus a regex, it's just another option. It's overkill for the OP's case. – JohnnyHK Aug 28 '16 at 02:16
  • 2
    Except regex is significantly slower. Fulltext searching is also slow, but not as slow. The fastest (but more bloated) way would be a separate field which is always set to lowercase. – Tom Mettam Jan 17 '18 at 00:37
  • 10
    Using full-text search is wrong in this case (and potentially *dangerous*), because the question was about making a case-insensitive query, e.g. `username: 'bill'` matching `BILL` or `Bill`, not a full-text search query, which would also match [stemmed words](https://docs.mongodb.com/manual/reference/operator/query/text/index.html#stemmed-words) of `bill`, such as `Bills`, `billed` etc. – Dan Dascalescu May 13 '19 at 05:32
10

One very important thing to keep in mind when using a Regex based query - When you are doing this for a login system, escape every single character you are searching for, and don't forget the ^ and $ operators. Lodash has a nice function for this, should you be using it already:

db.stuff.find({$regex: new RegExp(_.escapeRegExp(bar), $options: 'i'})

Why? Imagine a user entering .* as his username. That would match all usernames, enabling a login by just guessing any user's password.

Community
  • 1
  • 1
Nick Kamer
  • 101
  • 1
  • 4
9

Using Mongoose this worked for me:

var find = function(username, next){
    User.find({'username': {$regex: new RegExp('^' + username, 'i')}}, function(err, res){
        if(err) throw err;
        next(null, res);
    });
}
ChrisRich
  • 8,300
  • 11
  • 48
  • 67
9

Suppose you want to search "column" in "Table" and you want case insensitive search. The best and efficient way is:

//create empty JSON Object
mycolumn = {};

//check if column has valid value
if(column) {
    mycolumn.column = {$regex: new RegExp(column), $options: "i"};
}
Table.find(mycolumn);

It just adds your search value as RegEx and searches in with insensitive criteria set with "i" as option.

Pang
  • 9,564
  • 146
  • 81
  • 122
Ankur Soni
  • 5,725
  • 5
  • 50
  • 81
9

For searching a variable and escaping it:

const escapeStringRegexp = require('escape-string-regexp')
const name = 'foo'
db.stuff.find({name: new RegExp('^' + escapeStringRegexp(name) + '$', 'i')})   

Escaping the variable protects the query against attacks with '.*' or other regex.

escape-string-regexp

David Ortiz
  • 997
  • 1
  • 14
  • 22
8

Mongo (current version 2.0.0) doesn't allow case-insensitive searches against indexed fields - see their documentation. For non-indexed fields, the regexes listed in the other answers should be fine.

Aidan Feldman
  • 5,205
  • 36
  • 46
  • 21
    Just to clarify this: case-insensitive searches are _allowed_ on indexed fields, they just won't use the index and will be as slow as if the field wasn't indexed. – heavi5ide Dec 19 '11 at 17:22
  • @heavi5ide since this question is being used to mark duplicates I thought I would clarify that regexes (needed for case insensitive searches) do use the index, however, they must do a full index scan. In other words they cannot *efficiently* use the index. Fortunately the documentation has since been updated from 2011 but still good to note here too. – Sammaye Aug 13 '14 at 17:37
7

The best method is in your language of choice, when creating a model wrapper for your objects, have your save() method iterate through a set of fields that you will be searching on that are also indexed; those set of fields should have lowercase counterparts that are then used for searching.

Every time the object is saved again, the lowercase properties are then checked and updated with any changes to the main properties. This will make it so you can search efficiently, but hide the extra work needed to update the lc fields each time.

The lower case fields could be a key:value object store or just the field name with a prefixed lc_. I use the second one to simplify querying (deep object querying can be confusing at times).

Note: you want to index the lc_ fields, not the main fields they are based off of.

RobKohr
  • 6,611
  • 7
  • 48
  • 69
  • Nice solution but fortunately starting with MongoDB 3.4, there is native support for [Case Insensitive Indexes](https://stackoverflow.com/questions/1863399/mongodb-is-it-possible-to-make-a-case-insensitive-query/40914924#40914924). – Dan Dascalescu May 13 '19 at 07:00
6

If you're using MongoDB Compass:

Go to the collection, in the filter type -> {Fieldname: /string/i}

For Node.js using Mongoose:

Model.find({FieldName: {$regex: "stringToSearch", $options: "i"}})

jatinS
  • 566
  • 6
  • 6
5

The aggregation framework was introduced in mongodb 2.2 . You can use the string operator "$strcasecmp" to make a case-insensitive comparison between strings. It's more recommended and easier than using regex.

Here's the official document on the aggregation command operator: https://docs.mongodb.com/manual/reference/operator/aggregation/strcasecmp/#exp._S_strcasecmp .

Jogue Wasin
  • 67
  • 1
  • 4
5

You can use Case Insensitive Indexes:

The following example creates a collection with no default collation, then adds an index on the name field with a case insensitive collation. International Components for Unicode

/* strength: CollationStrength.Secondary
* Secondary level of comparison. Collation performs comparisons up to secondary * differences, such as diacritics. That is, collation performs comparisons of 
* base characters (primary differences) and diacritics (secondary differences). * Differences between base characters takes precedence over secondary 
* differences.
*/
db.users.createIndex( { name: 1 }, collation: { locale: 'tr', strength: 2 } } )

To use the index, queries must specify the same collation.

db.users.insert( [ { name: "Oğuz" },
                            { name: "oğuz" },
                            { name: "OĞUZ" } ] )

// does not use index, finds one result
db.users.find( { name: "oğuz" } )

// uses the index, finds three results
db.users.find( { name: "oğuz" } ).collation( { locale: 'tr', strength: 2 } )

// does not use the index, finds three results (different strength)
db.users.find( { name: "oğuz" } ).collation( { locale: 'tr', strength: 1 } )

or you can create a collection with default collation:

db.createCollection("users", { collation: { locale: 'tr', strength: 2 } } )
db.users.createIndex( { name : 1 } ) // inherits the default collation
Gencebay
  • 481
  • 2
  • 8
  • 15
  • There seems minor syntax issue(missing Braces).Please update the query: `db.users.createIndex( { name: 1 }, {collation: { locale: 'tr', strength: 2 } } )` – Mohd Belal Apr 12 '18 at 11:56
5

I'm surprised nobody has warned about the risk of regex injection by using /^bar$/i if bar is a password or an account id search. (I.e. bar => .*@myhackeddomain.com e.g., so here comes my bet: use \Q \E regex special chars! provided in PERL

db.stuff.find( { foo: /^\Qbar\E$/i } );

You should escape bar variable \ chars with \\ to avoid \E exploit again when e.g. bar = '\E.*@myhackeddomain.com\Q'

Another option is to use a regex escape char strategy like the one described here Javascript equivalent of Perl's \Q ... \E or quotemeta()

I.G. Pascual
  • 5,818
  • 5
  • 42
  • 58
2

Use RegExp, In case if any other options do not work for you, RegExp is a good option. It makes the string case insensitive.

var username = new RegExp("^" + "John" + "$", "i");;

use username in queries, and then its done.

I hope it will work for you too. All the Best.

2

If there are some special characters in the query, regex simple will not work. You will need to escape those special characters.

The following helper function can help without installing any third-party library:

const escapeSpecialChars = (str) => {
  return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
}

And your query will be like this:

db.collection.find({ field: { $regex: escapeSpecialChars(query), $options: "i" }})

Hope it will help!

talha_ah
  • 314
  • 6
  • 12
1

Using a filter works for me in C#.

string s = "searchTerm";
    var filter = Builders<Model>.Filter.Where(p => p.Title.ToLower().Contains(s.ToLower()));
                var listSorted = collection.Find(filter).ToList();
                var list = collection.Find(filter).ToList();

It may even use the index because I believe the methods are called after the return happens but I haven't tested this out yet.

This also avoids a problem of

var filter = Builders<Model>.Filter.Eq(p => p.Title.ToLower(), s.ToLower());

that mongodb will think p.Title.ToLower() is a property and won't map properly.

A_Arnold
  • 3,195
  • 25
  • 39
1

I had faced a similar issue and this is what worked for me:

  const flavorExists = await Flavors.findOne({
    'flavor.name': { $regex: flavorName, $options: 'i' },
  });
Woppi
  • 5,303
  • 11
  • 57
  • 81
  • This solution had already been give twice before. Please check existing answers before posting a new one. – Dan Dascalescu May 13 '19 at 05:36
  • 1
    @DanDascalescu not sure what you are talking about, upon CTRL+F, the similar solution with many upvotes posted it on September 2018. I posted my answer April 2018. I actually posted this because there is none at that time. Please also check when it was posted before warning those who just genuinely try to help. – Woppi May 16 '19 at 06:51
  • I'm talking about [this answer](https://stackoverflow.com/a/36956271/1269037) from April 2016, and [this answer](https://stackoverflow.com/a/37068312/1269037) from May 2016. Both use `$regex` and `$options`. What did you Ctrl+F? – Dan Dascalescu May 16 '19 at 07:17
  • Also, using `$regex` is inefficient and potentially insecure, as I've explained in my edit to [this other 2016 answer](https://stackoverflow.com/a/40914924/1269037). There's no shame in deleting answers if they no longer serve the community! – Dan Dascalescu May 16 '19 at 07:19
  • Noted on inefficient $regex, thanks a lot. I Ctrl+F $options. We are only two here with no new Regexp in our $regex code, Apr 2018 and Sep 2018. I didn't use new Regexp in my answer. I forgot the specific issue I had with new Regexp that is resolved when I removed it and just use this solution I posted instead. – Woppi May 16 '19 at 09:17
1

Yes it is possible

You can use the $expr like that:

           $expr: {
                $eq: [
                    { $toLower: '$STRUNG_KEY' },
                    { $toLower: 'VALUE' }
                ]
            }

Please do not use the regex because it may make a lot of problems especially if you use a string coming from the end user.

Mohamed Kamel
  • 282
  • 2
  • 8
0

I've created a simple Func for the case insensitive regex, which I use in my filter.

private Func<string, BsonRegularExpression> CaseInsensitiveCompare = (field) => 
            BsonRegularExpression.Create(new Regex(field, RegexOptions.IgnoreCase));

Then you simply filter on a field as follows.

db.stuff.find({"foo": CaseInsensitiveCompare("bar")}).count();
Nitesh
  • 822
  • 1
  • 8
  • 15
0

These have been tested for string searches

{'_id': /.*CM.*/}               ||find _id where _id contains   ->CM
{'_id': /^CM/}                  ||find _id where _id starts     ->CM
{'_id': /CM$/}                  ||find _id where _id ends       ->CM

{'_id': /.*UcM075237.*/i}       ||find _id where _id contains   ->UcM075237, ignore upper/lower case
{'_id': /^UcM075237/i}          ||find _id where _id starts     ->UcM075237, ignore upper/lower case
{'_id': /UcM075237$/i}          ||find _id where _id ends       ->UcM075237, ignore upper/lower case
Ar maj
  • 1,974
  • 1
  • 16
  • 16
0

For any one using Golang and wishes to have case sensitive full text search with mongodb and the mgo godoc globalsign library.

collation := &mgo.Collation{
    Locale:   "en",
    Strength: 2, 
}


err := collection.Find(query).Collation(collation)
okandas
  • 11,570
  • 2
  • 15
  • 17
-1

As you can see in mongo docs - since version 3.2 $text index is case-insensitive by default: https://docs.mongodb.com/manual/core/index-text/#text-index-case-insensitivity

Create a text index and use $text operator in your query.

avalanche1
  • 3,154
  • 1
  • 31
  • 38
  • Using full-text search is wrong in this case (and potentially *dangerous*), because the question was about making a case-insensitive query, e.g. `username: 'bill'` matching `BILL` or `Bill`, not a full-text search query, which would also match [stemmed words](https://docs.mongodb.com/manual/reference/operator/query/text/index.html#stemmed-words) of `bill`, such as `Bills`, `billed` etc. – Dan Dascalescu May 13 '19 at 05:34