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?
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);
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
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
}
}
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"
}
]
}
_id
is a field rather than a constraint.
_id = mongoose.Types.ObjectId()
, would that _id be unique across collection then?
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
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.
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;
Success story sharing
_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.{ _id: false }
, both levels of sub-schema are without ids. Any way to work around this behavior?{ _id : true }
?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 thestudentSchema
but retained_id
creation on the objects in theperformance
array of sub-documents. Not sure if both_id: false
andid: false
are needed.