Duplicate Key Error when a Schema has an array of another Schema with a unique index
See original GitHub issueDo you want to request a feature or report a bug?
Bug
What is the current behavior?
Assume we have a schema with a unique index on a field.
Then, we have another schema that has an array of the other schema.
I try to save 2 elements of ‘other schema’ with the same array (e.g. empty arrays) and I get duplicate error.
If the current behavior is a bug, please provide the steps to reproduce.
Here is an example:
const mongoose = require('mongoose')
const childSchema = new mongoose.Schema({
name: {
type: String,
unique: true,
},
})
const fatherSchema = new mongoose.Schema({
children: [childSchema],
name: String,
})
const childModel = mongoose.model('child', childSchema)
const fatherModel = mongoose.model('father', fatherSchema)
async function main() {
await mongoose.connect('mongodb://localhost:27017/bugtest')
const child1 = new childModel({
name: 'name1',
})
const child2 = new childModel({
name: 'name2',
})
await child1.save()
await child2.save()
const father1 = new fatherModel({
children: [],
name: 'father1',
})
await father1.save()
const father2 = new fatherModel({
children: [],
name: 'father2',
})
// This one fails
await father2.save()
}
main()
This is the error:
UnhandledPromiseRejectionWarning: MongoServerError: E11000 duplicate key error collection: bugtest.fathers index: children.name_1 dup key: { children.name: null }
I think the problem is that a unique index on children.name
is created automatically, hence when MongoDB finds 2 identical arrays, it marks them as the same.
What is the expected behavior?
No duplicate key error, since the unique field should only be on the 'child` schema and not on the array in the ‘father’ schema
What are the versions of Node.js, Mongoose and MongoDB you are using? Note that “latest” is not a version.
Node.js: 12.21.0 Mongoose: 6.1.2 MongoDB: 4.4
Issue Analytics
- State:
- Created 2 years ago
- Comments:12
The behavior described in original post is expected. Mongoose builds indexes on nested schemas by default, so the below will create an index on
children.name
:However, you can set the
excludeIndexes
option to prevent Mongoose from building indexes on an embedded schema:You can also use
ref
, but you’re right that embedding is generally faster.If you are using a ref, you don’t need to have the name property in the children array. Just make sure when you create father documents you also insert the correct _id that references the child document. When you query for father documents, just populate the document and it will give you the name because it uses the _id to find that correct document. From the documentation, this would seem to be the correct behavior. I will now mark this as a feature request as it seems to be what you are asking for now.