finOne() in mongoose fails with MongoServerError: Expected field collationto be of type object

Issue

I am trying to implement a simple registration validation using express and MongoDb but the below line of code always fails with the below error

const emailExist = await User.findOne({email: req.body.email});

The Error

_\node_modules\mongodb\lib\cmap\connection.js:203
                callback(new error_1.MongoServerError(document))
                         ^

MongoServerError: Expected field collationto be of type object
at Connection.onMessage (C:\Users\moham\Desktop\NetRe_\node_modules\mongodb\lib\cmap\connection.js:203:30)
at MessageStream.<anonymous> (C:\Users\moham\Desktop\NetRe_\node_modules\mongodb\lib\cmap\connection.js:63:60)
at MessageStream.emit (node:events:394:28)
at processIncomingData (C:\Users\moham\Desktop\NetRe_\node_modules\mongodb\lib\cmap\message_stream.js:108:16)
at MessageStream._write (C:\Users\moham\Desktop\NetRe_\node_modules\mongodb\lib\cmap\message_stream.js:28:9)
at writeOrBuffer (node:internal/streams/writable:389:12)
at _write (node:internal/streams/writable:330:10)
at MessageStream.Writable.write (node:internal/streams/writable:334:10)
at TLSSocket.ondata (node:internal/streams/readable:754:22)
at TLSSocket.emit (node:events:394:28) {


ok: 0,
code: 14,
codeName: 'TypeMismatch',
'$clusterTime': {
 clusterTime: Timestamp { low: 25, high: 1650230278, unsigned: true },
signature: {
  hash: Binary {
    sub_type: 0,
    buffer: Buffer(20) [Uint8Array] [
       74, 137, 251, 211, 139, 236,
       64,  99,  37,  21,  24, 232,
      160,  41,  22, 158,  46,  34,
       97, 169
    ],
    position: 20
  },
  keyId: Long { low: 2, high: 1641040568, unsigned: false }
}
},
operationTime: Timestamp { low: 25, high: 1650230278, unsigned: true },
[Symbol(errorLabels)]: Set(0) {}
}

The User Model structure

const mongoose = require ('mongoose')
const userSchema = new mongoose.Schema({

firstName: {type: String, required:true},
lastName: {type: String, required:true},
date: {type: Date},
id: {type: String, required:true, unique: true},
idType: {type: String, required:true},
gender: {type: String, required:true},
mobile: {type: String, required:true, unique: true},
email: {type: String, required:true},
password: {type: String, required:true, max: 1024, min: 6}
},
{ collation: 'user-data'})

const model = mongoose.model ('User', userSchema)

module.exports = model

Express server code

router.post('/register', async (req,res)=>{

//validate data before insert
const { error } = registerValidation(req.body);
if(error) {
    return res.status(400).send(error.details[0].message)  
}

//Checking if the user is already int the database
const emailExist = await User.findOne({email: req.body.email});
if(emailExist) {
    return res.status(400).send('Email already exists')
}

//Create new user
const user= new User(req.body);
try {

    const savedUser = await user.save();
    res.send(savedUser)
} catch (error) {
    res.status(400).send(err);
}
})

module.exports = router;

Solution

As the error states, it is looking for collation to be an object, you have it as a string. I am not sure what you are using the user-data string in the collation for. According to the docs:

Collation allows users to specify language-specific rules for string comparison, such as rules for lettercase and accent marks.

So in order to use it, the locale field is mandatory. If you are sure you are wanting a collation on this schema, the simplest way would be to change your schema to this:

const userSchema = new mongoose.Schema({
  firstName: {type: String, required:true},
  lastName: {type: String, required:true},
  date: {type: Date},
  id: {type: String, required:true, unique: true},
  idType: {type: String, required:true},
  gender: {type: String, required:true},
  mobile: {type: String, required:true, unique: true},
  email: {type: String, required:true},
  password: {type: String, required:true, max: 1024, min: 6}
},
{ collation: { locale: 'en_US', strength: 1 } })

Answered By – about14sheep

Answer Checked By – Mildred Charles (AngularFixing Admin)

Leave a Reply

Your email address will not be published.