0

I have a collection in which I store Email and password of user.

I obviously don't want to require the user to insert his email case sensitive and to be exactly as when he first registered.

I'm using mongodb 2.0 c# driver, I'm repeating it because I saw solutions to queries written with regex but I'm afraid I cant user it in here.

my query looks like

var filter = Builders<ME_User>.Filter.And(
                                 Builders<ME_User>.Filter.Eq(u => u.Email, email),
                                 Builders<ME_User>.Filter.Eq(u => u.Password, password));
            ME_User foundUser = null;
            var options = new FindOptions<ME_User>
            {
                Limit = 1
            };
            using (var cursor = await manager.User.FindAsync(filter, options))
            {
                while (await cursor.MoveNextAsync())
                {
                    var batch = cursor.Current;
                    foreach (ME_User user in batch)
                        foundUser = user;
                }
            }

I have an issue with disorder, kill me, but I cant allow myself save this data again with lower case and have 2 copies of the same thing. Also, I want the email to be saved EXACTLY like the user inserted it.

3 Answers 3

6

Filtering on string fields in Mongodb is case sensitive without using regular expressions. Why exactly you cannot use regular expressions?

Your query can be edited like this:

var filter = Builders<ME_User>.Filter.And(
Builders<ME_User>.Filter.Regex(u => u.Email, new BsonRegularExpression("/^" + email + "$/i"), 
Builders<ME_User>.Filter.Eq(u => u.Password, password));

Notice the "^" and "$" signs to specify a complete word search and most important the case-insensitive operator at the end of the regular expression ("/i").

Another way vould be the Text search, that requires the creation of a text index and is case insensitive for latin alphabet: http://docs.mongodb.org/manual/reference/operator/query/text/#match-operation

In C#, you will use with the Text Filter:

var filter = Builders<ME_User>.Filter.And(
Builders<ME_User>.Filter.Text(email), 
Builders<ME_User>.Filter.Eq(u => u.Password, password));

With a text index query in an OR clause, you will need to create an index on Password field as well, otherwise the OR query will produce an error:

Other non-TEXT clauses under OR have to be indexed as well

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

2 Comments

yeah, i meant no regex cause i saw people writing entire string object and not using the actual 2.0 driver. thats perfect!
Worked great! Regex saves the day once again.
3

I'd prefer using Linq.

var match = theCollection.AsQueryable().SingleOrDefault(x =>
    x.Email.ToLower() == emailToSearchFor.ToLower());

4 Comments

Yea that seems to work. I suppose you deserve an upvote.. but is it the most efficient way to do it? What if I have 200+ million documents?
@ppumkin I don't know if it is the most effective way you'd have to benchmark that. On the other hand, to me, it is far more readable. Are you planning to have 200+ million users? Can I buy some stocks? :)
Ummmm - Hahha I wish. No I am indexing documents from this game, PathOfExile and I have a subset of data now, 50million documents. I have tried Elastic, RavenDB, MongoDB to see which one is fastest. MongoDB is the worst for me.. 50seconds for the same query Elastic only 0.2second -- Umm, Yea?! But Elastic queries are super weird and also sometimes suffers 50second response times (but only sometimes). Maybe I am doing this wrong? :D I have no idea
I lost so much time because I used .Equals() which is not supported but == is. Thanks for your answer
0

For the c# driver 2.1 (MongoDB 3.0) By default its case-sensitive. To case-insensitive just add of "i" in BsonRegularExpression. please refer below

  var filter = Builders<Users>.Filter.Regex(k=>k.Name, new BsonRegularExpression(name, "i"));

  var users = await _mongoDbContext.Users.Find(filter).ToListAsync();

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.