How to allow unique fields in subdocuments when using mongoose? - node.js

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.

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

How to update a specific object in a array of objects by Item ID in Node.js and Mongoose

I need a code in Express.Js and Mongodb where I can change an exact string inside an object through the id of the item, I need to change the string "colorSelected" to a new value, changing only what I put in the body, in my previous failed attempts every change I made would change the entire object, I don't want that, thank you in advance.
Router Cart.js
//update color cart
router.patch("/cart/:id", Auth, async (req, res) => {
});
Model Cart.js
const mongoose = require('mongoose')
const ObjectID = mongoose.Schema.Types.ObjectId
const cartSchema = new mongoose.Schema({
owner : {
type: ObjectID,
required: true,
ref: 'User'
},
items: [{
itemId: {
type: ObjectID,
ref: 'Item',
required: true
},
img: String,
name: String,
colorSelected: String,
colors: Array,
stock: Number,
quantity: {
type: Number,
required: true,
min: 1,
default: 1
},
price: Number
}],
bill: {
type: Number,
required: true,
default: 0
}
}, {
timestamps: true
})
const Cart = mongoose.model('Cart', cartSchema)
module.exports = Cart
Model Item.js
const mongoose = require('mongoose')
const ObjectID = mongoose.Schema.Types.ObjectId
const reviewSchema = mongoose.Schema(
{
name: { type: String, required: true },
rating: { type: Number, required: true },
comment: { type: String, required: true },
user: {
type: ObjectID,
required: true,
ref: 'User'
},
},
{
timestamps: true,
}
)
const itemSchema = new mongoose.Schema({
images: [{
name: {
type: String,
required: true
},
src: {
type: String,
required: true
},
color: {
type: String,
required: true
},
}],
owner : {
type: ObjectID,
required: true,
ref: 'User'
},
name: {
type: String,
required: true,
trim: true
},
description: {
type: String,
required: true
},
category: {
type: Number,
required: true
},
price: {
type: Number,
required: true
},
stock: {
type: Number,
required: true
},
visibility: {
type: Boolean,
required: true
},
reviews: [reviewSchema],
rating: {
type: Number,
required: true,
default: 0,
},
numReviews: {
type: Number,
required: true,
default: 0,
}
}, {
timestamps: true
})
const Item = mongoose.model('Item', itemSchema)
module.exports = Item

How to get objectId of user in mongoose

I am currently working on a user registration setup. In the user model, I have defined apiKey as a property of the user and I want to set it equal to the user object Id. How can I do this ? Here is my code for the model :
const userScheama = new mongoose.Schema(
{
email: {
type: String,
trim: true,
required: true,
unique: true,
lowercase: true
},
name: {
type: String,
trim: true,
required: true
},
hashed_password: {
type: String,
required: true
},
apiKey:{
type: String,
required: false,
},
plan:{
type: String,
required: false
},
salt: String,
role: {
type: String,
default: 'subscriber'
},
resetPasswordLink: {
data: String,
default: ''
}
},
{
timestamps: true
}
);
You can use mongoose hooks here. First you need to update your apiKey to apiKey: {type:Schema.Types.ObjectId required: false }, and then add the below code to your model file
userScheama.pre('save', async function (next) {
this.apiKey = this._id;
next();
});

Creating Two Foreign key mongoose inside a controller

Hi I want to implement this snippet of my class diagram using mongoose.
Here is my logic model in detail:
Here is the definition of my Mother model:
const mongoose = require('mongoose')
const motherSchema = mongoose.Schema({
cniMother: { type: Number, required: true },
name: { type: String, required: true },
surname: { type: String, required: true },
birthDay: { type: Date, required: true },
birthPlace: { type: String, required: true },
address: { type: String, required: true },
phone: { type: Number, required: true },
occupation: { type: String, required: true },
});
module.exports = mongoose.model('Mother', motherSchema);
Here is the definition of my Declared model:
const mongoose = require('mongoose')
const declaredSchema = mongoose.Schema({
name: { type: String, required: true },
surname: { type: String, required: true },
father: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Father',
//required: true,
},
mother: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Mother',
//required: true,
},
birthDay: { type: Date, required: true },
birthPlace: { type: String, required: true },
gender: { type: String, required: true },
nationality: { type: String, required: true }
});
module.exports = mongoose.model('Declared', declaredSchema);
I want to retrieve the name of the father and the mother corresponding to the declared.
Can anyone help me please?

nodejs mongoose : cyclic dependency detected

I'm getting a cyclic dependency exception whereas I don't find any cyclic possibility in the very simple code at this point. I'm expecting it is happening due to population between two mongoose models but as said here : mongoose - possible circular dependency? this shouldn't produce this kind of error so I don't understand.
model\customer.js
var mongoose = require('mongoose'), Schema = mongoose.Schema;
var customerSchema = new Schema({
_siretCustomer:
{ type: String, required: true, minlength: 15, maxlength: 15, index: {unique: true} },
fileNumberCustomer:
{ type: String, required: true, minlength: 6, maxlength: 6 },
companyTypeCustomer:
{ type: String, required: true },
companyNameCustomer:
{ type: String, required: true },
contactName1Customer:
{ type: String, required: false, default: null },
contactName2Customer:
{ type: String, required: false, default: null },
landlineContact1Customer:
{ type: String, required: false, default: null },
landlineContact2Customer:
{ type: String, required: false, default: null },
emailContactCustomer:
{ type: String, required: false, default: null },
obligationCommentCustomer:
{ type: String, required: false, default: null },
taskCommentCustomer:
{ type: String, required: false, default: null },
creationDateCustomer:
{ type: Date, default: Date.now },
userCustomer:
[{ type: Schema.Types.ObjectId, ref: 'User', required: true }]
}, { collection: 'customer' });
module.exports = mongoose.model('Customer', customerSchema, 'customer');`
model\user.js
var mongoose = require('mongoose'), Schema = mongoose.Schema;
var userSchema = new Schema({
_trigramUser:
{ type: String, required: true, index: { unique: true } },
lastnameUser:
{ type: String, required: true },
firstnameUser:
{ type: String, required: true },
privilegeUser:
{ type: String, required: true, enum: ['Accountant', 'Social operator'] },
dateCreationUser:
{ type: Date, default: Date.now },
passwordUser:
{ type: String, required: true },
customersUser:
[{ type: String, ref: 'Customer'}]
}, { collection: 'user'});
module.exports = mongoose.model('User', userSchema, 'user');
controller\session\customerController.js
exports.readCustomer = (req, res) => {
database.getConnection();
customer.find(req).populate('userCustomer').exec((err, customer) => {
if (err) return res.status(500).json(err.stack);
res.status(200).json(customer);
});
};

find according to referenced objectid

i have this schema:
var scheme = schema({
name: { type: String, required: true },
deleted: { type: Boolean, default: false },
user: {
type: ObjectId,
ref: 'User'
},
created: {type: Date, default: Date.now},
modified: {type: Date, default: Date.now},
eventinfo: { type: String, required: false },
street: { type: String, required: false },
city: { type: String, required: false },
country: { type: String, required: false },
postalcode: { type: String, required: false },
usecurrentlocation: { type: Boolean, required: false },
schedule_agenda_html: { type: String, required: false },
gspsetup_html: { type: String, required: false },
evdropboxstat: { type: Boolean, required: false },
evsponsors_html: { type: String, required: false },
evexhibitors_html: { type: String, required: false },
floorplan_html: { type: String, required: false },
social_media_fb: { type: String, required: false },
social_media_tw: { type: String, required: false },
social_media_li: { type: String, required: false },
evorganizers_html: { type: String, required: false },
coverscreen_img: { type: String, required: false },
logo_img: { type: String, required: false },
background_img: { type: String, required: false },
background_color: { type: String, required: false },
event_fromdate: {type: Date, default: Date.now},
event_todate: {type: Date, default: Date.now},
attendees_feedback: { type: Boolean, required: false },
social_network: { type: Boolean, required: false },
feature_icon_color: { type: String, required: false }
});
exports.EacEvent = mongoose.model("EacEvent", scheme);
i need to find all the EacEvents where user _id is equal to some thing like this (56a8a1eaf7a3289c10c9ed30) i have tried many things but either i am getting all the EacEvents or no EacEvent. thanks
Route File
here is my route file code which i am using to get the required results..
var models = require('../models')
,mongoose = require('mongoose')
var schema = mongoose.Schema;
var ObjectId = schema.ObjectId;
// var ObjectID = schema.ObjectId;
exports.myeventapps = function (req, res) {
var eac_userid;
if (req.user){
eac_userid = JSON.stringify(req.user._id);
console.log('================================' + eac_userid);
}
//models.EacEvent.find().exec(function(err, myevents) {
models.EacEvent.find({ deleted: false,'user._id':ObjectId(eac_userid)}).sort({ modified: -1 }).exec(function(err, myevents) {
res.locals.myevents = myevents;
console.log('================================' + myevents);
res.render('eac_myevent_apps', { title: "My Event Apps", myeventapps: myevents });
});
}
i have also tried comparing user._id in .populate() function but did not get the required results
Please try it, match user field directly, rather than user._id.
Refer to Mongoose Populate.
models.EacEvent.find({ deleted: false, 'user': ObjectId(eac_userid)}).sort(...
Maybe we can use the req.user._id directly
models.EacEvent.find({ deleted: false, 'user': req.user._id}).sort(...

Resources