Stop Mongoose from creating _id property for sub-document array items
Asked Answered
S

8

331

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?

Soinski answered 22/6, 2013 at 18:28 Comment(0)
Y
442

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);
Ylangylang answered 22/6, 2013 at 18:44 Comment(4)
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.Safier
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?Safier
Have you try, for the third level to set { _id : true } ?Ylangylang
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.Safier
P
214

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

Paderewski answered 13/12, 2013 at 2:43 Comment(0)
E
62

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
   }
}
Exhalant answered 28/5, 2014 at 5:12 Comment(0)
L
33

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"
      }
    ]
}
Lunate answered 14/10, 2016 at 23:8 Comment(4)
is there a way to make unique across entire collection?Economically
Probably not with this method, but you could always try. _id is a field rather than a constraint.Lunate
if during the creation of that sub-document, i explicitly assign _id = mongoose.Types.ObjectId(), would that _id be unique across collection then?Economically
just open a new stack overflow, this way you can get many people to answer at once~Lunate
W
7

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

Waistline answered 25/4, 2019 at 6:21 Comment(0)
E
5

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;
Ennis answered 4/4, 2022 at 3:37 Comment(0)
L
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.

Lani answered 4/4, 2020 at 9:7 Comment(0)
D
1

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 },
Derick answered 20/1 at 9:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.