342

If you have subdocument arrays, Mongoose automatically creates ids for each one. Example:

{
    _id: "mainId"
    subDocArray: [
      {
        _id: "unwantedId",
        field: "value"
      },
      {
        _id: "unwantedId",
        field: "value"
      }
    ]
}

Is there a way to tell Mongoose to not create ids for objects within an array?

8 Answers 8

455

It's simple, you can define this in the subschema :

var mongoose = require("mongoose");

var subSchema = mongoose.Schema({
    // your subschema content
}, { _id : false });

var schema = mongoose.Schema({
    // schema content
    subSchemaCollection : [subSchema]
});

var model = mongoose.model('tablename', schema);
Sign up to request clarification or add additional context in comments.

4 Comments

will this skip _id fields even in the subSchema collection, or only in the case where the subSchema is being used to embed as array of sub-document items? I ask this particularly because of my own question on SO today.
I use two levels of nested sub-schema collections. In other words, I have a subSchema collection similar to your example. Within that, I use another different sub-schema collection. I want only the first level sub-schema model instances to not use ids, but the second level (nested) sub-schema model instances need to have ids. When I use your solution, that is, specifying { _id: false }, both levels of sub-schema are without ids. Any way to work around this behavior?
Have you try, for the third level to set { _id : true } ?
what I tried yesterday was change this: let studentSchema = new Schema({ studentId: { type: ObjectId, ref: Student.modelName }, performance: [performanceSchema] }, { _id: false }); to this: let studentSchema = new Schema({ _id: false, id: false, studentId: { type: ObjectId, ref: Student.modelName }, performance: [performanceSchema] }); and that stopped _id creation on the studentSchema but retained _id creation on the objects in the performance array of sub-documents. Not sure if both _id: false and id: false are needed.
219

You can create sub-documents without schema and avoid _id. Just add _id: false to your subdocument declaration.

var schema = new mongoose.Schema({
   field1: {
      type: String
   },
   subdocArray: [{
      _id: false,
      field: { type: String }
   }]
});

This will prevent the creation of an _id field in your subdoc.

Tested in Mongoose v5.9.10

1 Comment

This still works even with Mongoose v8.3.0. Tested it myself.
63

Additionally, if you use an object literal syntax for specifying a sub-schema, you may also just add _id: false to supress it.

{
   sub: {
      property1: String,
      property2: String,
      _id: false
   }
}

Comments

34

I'm using mongoose 4.6.3 and all I had to do was add _id: false in the schema, no need to make a subschema.

{
    _id: ObjectId
    subDocArray: [
      {
        _id: false,
        field: "String"
      }
    ]
}

4 Comments

is there a way to make unique across entire collection?
Probably not with this method, but you could always try. _id is a field rather than a constraint.
if during the creation of that sub-document, i explicitly assign _id = mongoose.Types.ObjectId(), would that _id be unique across collection then?
just open a new stack overflow, this way you can get many people to answer at once~
8

You can use either of the one

var subSchema = mongoose.Schema({
//subschema fields    

},{ _id : false });

or

var subSchema = mongoose.Schema({
//subschema content
_id : false    

});

Check your mongoose version before using the second option

Comments

6

NestJS example for anyone looking for a solution with decorators

@Schema({_id: false})
export class MySubDocument {
    @Prop()
    id: string;
}

Below is some additional information from the Mongoose Schema Type definitions for id and _id:

/**
* Mongoose assigns each of your schemas an id virtual getter by default which returns the document's _id field
* cast to a string, or in the case of ObjectIds, its hexString.
*/
id?: boolean;

/**
* Mongoose assigns each of your schemas an _id field by default if one is not passed into the Schema
* constructor. The type assigned is an ObjectId to coincide with MongoDB's default behavior. If you
* don't want an _id added to your schema at all, you may disable it using this option.
*/
_id?: boolean;

Comments

4

If you want to use a predefined schema (with _id) as subdocument (without _id), you can do as follow in theory :

const sourceSchema = mongoose.Schema({
    key : value
})
const subSourceSchema = sourceSchema.clone().set('_id',false);

But that didn't work for me. So I added that :

delete subSourceSchema.paths._id;

Now I can include subSourceSchema in my parent document without _id. I'm not sure this is the clean way to do it, but it work.

Comments

2

TypeError: Invalid schema configuration: false is not a valid type at path id.

_id: { id: false },

If adding this line makes your app show the error message mentioned above, you might be using the newest mongoose 7 module versions.

To solve it, modify the mentioned line by adding an underscore _ before the id in the { _id: false } syntax on that line. So, that line should now look like this:

_id: { _id: false },

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.