I Have a schema like so:
class Schemas
constructor: ->
@mongoose = require 'mongoose'
@schema = @mongoose.Schema
@EmployeeSchema = new @schema
'firstname': { type: String, required: true },
'lastname': { type: String, required: true },
'email': { type: String, required: true, index: { unique: true }, validate: /\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}\b/ },
'departmentId': { type: @schema.ObjectId, required: true }
'enddate': String,
'active': { type: Boolean, default: true }
@EmployeeSchemaModel = @mongoose.model 'employees', @EmployeeSchema
@DepartmentSchema = new @schema
'name': { type: String, required: true, index: { unique: true } }
'employees' : [ @EmployeeSchema ]
@DepartmentSchemaModel = @mongoose.model 'departments', @DepartmentSchema
So that my employees live in an array of employee documents inside a department
I have several department documents that have a number of employee documents stored in the employees array.
I then added a new department but it contained no employees. If I then attempt to add another department without employees, Mongoose produces a Duplicate key error for the employee.email field which is a required field. The employee.email field is required and unique, and it needs to be.
Is there anyway round this?
If you enable Mongoose debug logging with the coffeescript equivalent of
mongoose.set('debug', true);you can see what’s going on:By embedding the full
EmployeeSchemain theemployeesarray ofDepartmentSchema(rather than just anObjectIdreference to it), you end up creating unique indexes on bothemployees.emailanddepartment.employees.email.So when you create a new
departmentwithout any employees you are ‘using up’ the undefined email case in thedepartment.employees.emailindex as far a uniqueness. So when you try and do that a second time that unique value is already taken and you get theDuplicate key error.The best fix for this is probably to change
DepartmentSchema.employeesto an array ofObjectIdreferences to employees instead of full objects. Then the index stays in theemployeescollection where it belongs and you’re not duplicating data and creating opportunities for inconsistencies.