0

I have defined these three models in mongoose:

const clientSchema = new mongoose.Schema({
  name: String,
  role: String,
  age: {
     type: Number,
     default: 10
  }
})
clientSchema.pre('save', function(){
  const doc = this
  doc.role = 'client'
})
const adminSchema = new mongoose.Schema({
  name: String,
  role: String,
})
adminSchema.pre('save', function(){
  const doc = this
  doc.role = 'admin'
})
const userSchema = new mongoose.Schema({
  name: String,
  role: String,
  age: {
     type: Number,
     default: 10
  },
})
const AdminModel = mongoose.model('AdminModel', AdminModel, 'users')
const ClientModel = mongoose.model('ClientModel', ClientModel, 'users')
const UserModel = mongoose.model('UserModel', UserModel, 'users')

and I have the following route in my express app:

app.route('/users').get(async(req, res, next)=>{
   const docs = UserModel.find({ role: 'admin' })
})

It works as expected, except that it's returning the following to the client-side:

{
  "name": "James Breakers",
  "role": "admin",
  "age": 10
}

and this is wrong, and it causes many problems.

On write, it works great, it saves it in the database without the age: 10, but the problem is when retrieving (reading) from the database, Mongoose is setting the field age: 10.

and All of that is only because I used the UserModel to retrieve that admin. But I don't want that default behavior of Mongoose at all.

How can I disable it? is there a schema option for that?

Normal
  • 1,616
  • 15
  • 39
  • When your schema field has a `default`, doesn't it get written to the document in the collection. "it saves it in the database without the age: 10" ... [are you sure](https://mongoosejs.com/docs/defaults.html)? [Possibly related ...](https://stackoverflow.com/questions/35066362/do-mongoose-defaults-get-applied-to-existing-documents) – rickhg12hs Sep 02 '22 at 15:13
  • @rickhg12hs, hi. it depends on the model I use for writing the data to the database, for instence, here I have three models [ClientModel, AdminModel, UserModel]. If I used ClientModel or UserModel to write the data to the database then yes it saves `age:10`. While if I used the Admin model to write to the database, it doesn't – Normal Sep 02 '22 at 15:49
  • @rickhg12hs, this is the correct behavior, as I mentioned up there, it works great when writing, but when reading, it writes the default to the response that gets send to the client – Normal Sep 02 '22 at 15:50
  • i.e. in the database, if you looked using Mongo Compass, you'll see that the document is getting saved without `age: 10`, which is correct. But the problem is happening on the server side because of mongoose. Mongoose is writing these defaults to me which is not what I want. I want to disable – Normal Sep 02 '22 at 15:51
  • Could you use [`lean`](https://mongoosejs.com/docs/api.html#query_Query-lean)? – rickhg12hs Sep 02 '22 at 18:25
  • @rickhg12hs, actually no, but it's partly possible after completing all the tasks on the backend, you can then use the `lean` method before sending the response. But here I will have two major problems, first, lean is going to remove the virtual fields from the response object, and I must have these in the response (actually I have many of them). and the second problem is that I will have to convert all my existing codebase to use the `.lean` method, which can then cause millions of bugs if not tested correctly – Normal Sep 03 '22 at 04:10
  • I use MongoDB schema-less with provided drivers and that works great for me. I can't represent technical measurements with schema defaults, only data from sensors. You have a hard problem managing data stored/retrieved with different schemas. I don't know how you will solve it. – rickhg12hs Sep 03 '22 at 13:31
  • 1
    @rickhg12hs, I'm moving to mysql database in my next major version of my system, I strongly believe that would be better.. anyway, I managed to solve this problem by following this answer https://stackoverflow.com/a/47824516/18387350 – Normal Sep 04 '22 at 09:35

0 Answers0