Home > Enterprise >  How to allow unique fields in subdocuments when using mongoose?
How to allow unique fields in subdocuments when using mongoose?

Time:01-10

I'm using mongoose to to define 2 schemas.

employee.js

const mongoose = require("mongoose");
const uniqueValidator = require("mongoose-unique-validator");
const Role = require("./role");

const employeeSchema = mongoose.Schema({
  code: { type: String, required: true, unique: true, index: true },
  names: { type: String, required: true },
  last_names: { type: String, required: true },
  role: Role.schema,
  dui: { type: String, required: true, unique: true, index: true },
  nit: { type: String, required: false, unique: true, index: true },
  sex: { type: String, required: false },
  civil_status: { type: String, required: false },
  birthday: { type: Date, required: false },
  telephone: { type: String, required: true },
  city: { type: String, required: true },
  address: { type: String, required: true },
  active: { type: Boolean, required: true },
});


employeeSchema.plugin(uniqueValidator);

module.exports = mongoose.model("Employee", employeeSchema);

and role.js

const mongoose = require("mongoose");
const uniqueValidator = require("mongoose-unique-validator");

const roleSchema = mongoose.Schema({
  code: { type: String, required: true, unique: true, index: true },
  description: { type: String, required: true }
});

roleSchema.plugin(uniqueValidator);

module.exports = mongoose.model("Role", roleSchema);

The problem I have is that, whenever I insert a document with a role code that's repeated I get an error because of the unique validation. I have tried deleting

roleSchema.plugin(uniqueValidator);

from role.js and I have also tried using .set to alter the field in role.

const mongoose = require("mongoose");
const uniqueValidator = require("mongoose-unique-validator");
const Role = require("./role");

const subRole = Role.schema.clone().set('code', {unique: false}).set('code', {index : false});

const employeeSchema = mongoose.Schema({
  code: { type: String, required: true, unique: true, index: true },
  names: { type: String, required: true },
  last_names: { type: String, required: true },
  role: subRole,
  dui: { type: String, required: true, unique: true, index: true },
  nit: { type: String, required: false, unique: true, index: true },
  sex: { type: String, required: false },
  civil_status: { type: String, required: false },
  birthday: { type: Date, required: false },
  telephone: { type: String, required: true },
  city: { type: String, required: true },
  address: { type: String, required: true },
  active: { type: Boolean, required: true },
});


employeeSchema.plugin(uniqueValidator);

module.exports = mongoose.model("Employee", employeeSchema);

I always get an error saying that role code needs to be unique. Am I using .set incorrectly? or what am I missing? Thank you very much in advance.

CodePudding user response:

Solved it changing:

const subRole = Role.schema.clone().set('code', {unique: false}).set('code', `{index : false});`

to

const subRole = Role.schema.clone().set('excludeIndexes', true);

Deleted the employees's collection so it would recreate it with the right indexes and that did the trick.

It was mentioned in one of mongoose's issues in github: https://github.com/Automattic/mongoose/issues/11547

Supposedly they implemented something about it but I didn't get it. The above worked for me though.

  • Related