Mongoose: avoid empty object/array creation

Created on 27 May 2016  路  9Comments  路  Source: Automattic/mongoose

Hi, I find in my documents some fields like:

   ...
   my_array_of_obj_field: [{}],
   my_obj_field: {},
   my_str_field: "",

    ...

(the cause is angularjs in frontend that initializes the empty model)

what's the best way to avoid storing of those fields?

needs repro script

Most helpful comment

  • If you have an array in your schema, mongoose will create an empty array [] for you by default so you can do .push() and such without explicitly creating the array. To shut this off, overwrite the default array default (requires mongoose 4.4.15 or higher)
var schema = new Schema({
  myArr: { type: [String], default: undefined }
});
  • Empty objects shouldn't happen because of the minimize property, unless you explicitly set minimize: false.
  • For strings, set required: true and empty strings will no longer be allowed.

All 9 comments

Hi @antonioaltamura, I can suggest create a new schema type like NotEmpty http://mongoosejs.com/docs/customschematypes.htmland return undefined when value is empty. Or apply this checks in schema pre save
http://stackoverflow.com/questions/12636938/set-field-as-empty-for-mongo-object-using-mongoose

  • If you have an array in your schema, mongoose will create an empty array [] for you by default so you can do .push() and such without explicitly creating the array. To shut this off, overwrite the default array default (requires mongoose 4.4.15 or higher)
var schema = new Schema({
  myArr: { type: [String], default: undefined }
});
  • Empty objects shouldn't happen because of the minimize property, unless you explicitly set minimize: false.
  • For strings, set required: true and empty strings will no longer be allowed.

@vkarpov15 Thanks. I also want to make all the strings in the array in lowercase but this doesn't seem to work:

var schema = new Schema({
  myArr: { type: [String], lowercase: true, default: undefined }
});

What's the correct way of setting that?

This worked :)

var schema = new Schema({
  myArr: { type: [{type: String, lowercase: true}], default: undefined }
});

The above works well at create but not at findOneAndUpdate.

ModelName.create({ myArr: undefinedValue }) lowercases and doesn't set myArr

ModelName.findOneAndUpdate({ _id: 1 }, { $addToSet: { myArr: undefinedVar } }) doesn't lowercase and sets myArr to [ null ]

I'm using Mongoose 5.3.4 with Mongo 4.0.9

@anasqadrei ModelName.create({ myArr: undefinedValue }) doesn't set myArr because myArr is undefined by default.

What should ModelName.findOneAndUpdate({ _id: 1 }, { $addToSet: { myArr: undefinedVar } }) do to lowercase? You can't convert undefined to lowercase...

@vkarpov15 Opps. Correction is:
ModelName.findOneAndUpdate({ _id: 1 }, { $addToSet: { myArr: undefinedVar } })
sets myArr to [ null ], and
ModelName.findOneAndUpdate({ _id: 1 }, { $addToSet: { myArr: definedVar } }) doesn't lowercase definedVar

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true, useFindAndModify: false });
const db = mongoose.connection

const Cat = mongoose.model('Cat', {
  _id: String,
  myArr: { type: [{type: String, lowercase: true}], default: undefined }
});

(async () => {
  await Cat.create({ _id: 'One' })
  // result document is { _id: 'One' }

  await Cat.create({ _id: 'Two', myArr: [] })
  // result document is { _id: 'Two', myArr: [] }

  await Cat.create({ _id: 'Three', myArr: ['Case SenSiTive'] })
  // result document is { _id: 'Three', myArr: ['case sensitive'] }

  await Cat.create({ _id: 'Four' })
  await Cat.findOneAndUpdate({ _id: 'Four' }, { $addToSet: { myArr: undefined } })
  // result document is { _id: 'Four', myArr: [ null ] }

  await Cat.create({ _id: 'Five' })
  await Cat.findOneAndUpdate({ _id: 'Five' }, { $addToSet: { myArr: ['Case SenSiTive'] } })
  // result document is { _id: 'Five', myArr: [ 'Case SenSiTive' ] }

  db.close()
})()

The undefined to null is expected behavior unfortunately, see comments here. Will fix the lowercase issue.

Was this page helpful?
0 / 5 - 0 ratings