bthe0
bthe0

Reputation: 1434

Mongoose case insensitive schema

I am trying to make all find calls inside a schema be case insensitive. This is what I got so far:

const user = new new mongoose.Schema({
        username: {
            trim: true,
            required: true,
            type: String,
            match : [
                new RegExp('^[a-z0-9_.-]+$', 'i'),
                '{PATH} \'{VALUE}\' invalid'
            ],
            validate : [
                (username, callback) => {
                    console.log(username);

                    user.findOne({ username: new RegExp(`/^${username}$/i`) }, (err, doc) => {
                        if(!doc) return callback(false);
                        return callback(true);
                    });
                },
                'Username already exists'
            ]
        });

What am I doing wrong ?

Upvotes: 0

Views: 4664

Answers (2)

Cameron Newby
Cameron Newby

Reputation: 61

You can make your schema insensitive by defining what mongoDb calls a collation https://docs.mongodb.com/manual/core/index-case-insensitive/ when creating a new instance of a mongoose.Schema.

var someSchema = new mongoose.Schema({
   username: {type: String, required: true}
}, {
   collation: { locale: 'en', strength: 2 }
});

Now you have applied case-insenstitive logic on the schema level which will be reflected and used when querying the model of this schema.

someModel.findOne({username: 'UsERName1'})

The above query would now be made case-insensitive due to your collation on the models corresponding schema.

Upvotes: 4

bthe0
bthe0

Reputation: 1434

I managed to get this working through a middleware:

user.pre('find', function() {
    if (this._conditions.username) {
        this._conditions.username = new RegExp(this._conditions.username.replace(/\./g, '\\\\.'), 'i');
    }
});

Upvotes: 1

Related Questions