E11000 duplicate key error index in mongodb - mongodb

I have a collection named "Item" and schema look like
const mongoose = require("mongoose");
const ItemSchema = mongoose.Schema(
{
title: {
type: String,
required: [true, "Item name required"],
unique: false,
minLength: [4, "Cannot be less than 4 characters"],
maxLength: [40, "Cannot be greater then 40 characters"],
},
units: {
type: Number,
required: [true, "Item units required"],
min: [0, "Invalid value"],
},
mess: {
type: mongoose.Schema.Types.ObjectId,
ref: "Mess",
required: [true, "Mess name required"],
},
},
{
timestamps: true,
}
);
module.exports = mongoose.model("Item", ItemSchema);
Mess schema:
const mongoose = require("mongoose");
const MessSchema = mongoose.Schema({
name: {
type: String,
required: true,
unique: true,
uppercase: true,
},
}, {
timestamps: true,
});
module.exports = mongoose.model("Mess", MessSchema);
and let say i'm inserting data like
db.items.insertMany([{
"title": "chicken qorma",
"units": 160,
"mess": "63dde5547cf24f27a81cc82c"
},
{
"title": "chicken qorma",
"units": 160,
"mess": "63dde53a7cf24f27a81cc829"
}])
I tried many solutions but nothing is working. I need to duplicate "title".
"title" attribute should not be unique but getting an error "E11000 duplicate key error collection: MessIT.items index: name_1 dup key: { name: null }"

Related

Getting this error when adding a product to mongoDB

This is the file containing the Schema
let mongoose = require('mongoose');
let Schema = mongoose.Schema;
const productSchema = new Schema({
_id: {
type: Number,
required: true
},
product_name: {
type: String,
required: true
},
price: {
type: String,
required: true
},
quantity: {
type: Number,
required: true
},
product_collection: {
type: String,
required: true,
enum: ['Nike' , 'Addidas']
},
product_image_url: {
type: String,
required: true
},
product_type: [
{
color: {
type: String,
required: true,
}
},
{
size: {
type: Number,
required: true,
enum: ['40', '41' , '42']
}
}
]
})
const Product = mongoose.model('Product' , productSchema);
module.exports = Product;
This is the seeds file where i want to create a product
//Require Models
const mongoose = require('mongoose');
//Require Models
const Product = require('./models/product');
//Connecting to DB server
mongoose.connect('mongodb://localhost:27017/ecom', {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
console.log('DATABASE CONNECTED')
})
.catch(err => {
console.log('SOMETHING WENT WRONG WITH MONGO')
console.log(err)
})
const p = new Product({
_id: 1,
product_name: 'Nike HyperVenom',
price: 150,
quantity: 30,
product_collection: 'Nike',
product_image_url: 'zzzzz',
product_type: [
{
color: 'red'
},
{
size: [41 , 42]
}
]
})
p.save().then(p => {
console.log(p)
})
.catch(e => {
console.log(e)
})
This is the error that is displayed in console.
Error: Product validation failed: product_type.1.color: Path `color` is required
errors: {
'product_type.1.color': ValidatorError: Path `color` is required.
at validate (C:\Users\hadiz\Desktop\Business\portfolioprojects\ecommerce
\node_modules\mongoose\lib\schematype.js:1277:13)
at C:\Users\hadiz\Desktop\Business\portfolioprojects\ecommerce\node_modu
les\mongoose\lib\schematype.js:1260:7
at Array.forEach (<anonymous>)
at SchemaString.SchemaType.doValidate (C:\Users\hadiz\Desktop\Business\p
ortfolioprojects\ecommerce\node_modules\mongoose\lib\schematype.js:1210:14)
at C:\Users\hadiz\Desktop\Business\portfolioprojects\ecommerce\node_modu
les\mongoose\lib\document.js:2690:18
at processTicksAndRejections (node:internal/process/task_queues:76:11) {
properties: [Object],
kind: 'required',
path: 'color',
value: undefined,
reason: undefined,
[Symbol(mongoose:validatorError)]: true
}
},
_message: 'Product validation failed'
}
Any idea how to fix this , I am a bit of a beginner in mongoose and mongoDB. I think the problem is with the product_type section , am i giving them a value in the right way in the seeds file ?
The product_type object in your schema indicates that every object inside it must have a color key-value pair. The error was about your second object in product_type (index 1) does not have the color key. You should change product_type from an array to an object. I.E.
product_type: {
color: {
type: String,
required: true,
},
size: [{
type: Number,
required: true,
enum: [40, 41, 42]
}],
}
And your input should become:
product_type: {
color: "red",
size: [41, 42],
}

Why is validation in array of mongoose schema not working?

I have the following mongoose model:
const collaboratorDetailsSchema = new mongoose.Schema({
userId: {
type: mongoose.SchemaTypes.ObjectId,
ref: "User",
required: true
},
stacks: {
type: Array,
required: true,
default: undefined,
validate: {
validator: function (v) {
return v.length > 0;
},
message: "Atleast one stack must be provided",
},
},
experienceLevel: {
type: Number,
min: 1,
max: 5,
required: true,
},
note: {
type: String,
},
});
Then I have defined another schema which contains collaboratorDetailsSchema as an array.
const collaboratorSchema= new mongoose.Schema({
projectId: {
type: mongoose.SchemaTypes.ObjectId,
ref: "Project",
unique: true,
required: true,
},
collaborators: [collaboratorDetailsSchema],
});
And finally, created the MongoDB model as follows:
const Collaborator= mongoose.model("Collaborator", collaboratorSchema, "Collaborators");
But when I push objects into the collaborators array using findByIdAndUpdate command with $push, the required validation and the custom validation as defined in the collaboratorDetailsSchema are not enforced.
Which means I'm able to store the following document:
{
"_id": ObjectId("5f07e8c91027230f2429a7b3"),
"projectId": Objectid("5f07411154dd016500a8d585"),
"collaborators": [
{
"_id": ObjectId("5f07e8c91027230f2429a7b4"),
"stacks": [],
"experienceLevel": 10,
"note": "Sample Note"
}
],
"__v": 0
}
This should have given an error because
userId is not present (required: true specified in schema)
stacks is an empty array (requires minimum 1 element)
experienceLevel exceeds max value of 5
I'm using Postman for testing and "mongoose": "^5.9.20" and "express": "^4.17.1"

Mongoose - Validate ObjectID related document

I need to validate as required a field "product" in Model Event. Product is ObjectID reference to Product Model.
I tried with this 2 approaches, but it is not validating
product: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Product',
required: true
}]
},
product: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Product',
required: function () {
return this.product.length > 0
},
}]
},
The Event is being created anyway, and when I add no products, field product is an empty array.
Any idea how can I validate it?
Models:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Product = require('../models/Product');
const moment = require('moment');
const EventSchema = new Schema({
client: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Client'
}]
},
product: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Product',
required: true
}]
},
date: {
type: Date,
maxlength: 64,
lowercase: true,
trim: true
},
place: {
type: String,
maxlength: 1200,
minlength: 1,
},
price: {
type: Number
},
comment: {
type: String,
maxlength: 12000,
minlength: 1,
},
status: {
type: Number,
min: 0,
max: 1,
default: 0,
validate: {
validator: Number.isInteger,
message: '{VALUE} is not an integer value'
}
},
},
{
toObject: { virtuals: true },
toJSON: { virtuals: true }
},
{
timestamps: true
},
);
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Provider = require('./Provider')
const ProductSchema = new Schema({
name: {
type: String,
maxlength: 64,
minlength: 1,
required: [true, 'Product name is required'],
},
brand: {
type: String,
maxlength: 64,
minlength: 1,
},
description: {
type: String,
maxlength: 12000,
min: 1,
},
comment: {
type: String,
maxlength: 12000,
minlength: 1
},
state: {
type: String,
maxlength: 64,
minlength: 0
},
disponible: {
type: Boolean,
default: true
},
price: {
type: Number,
default: 0,
min: 0,
max: 999999
},
provider: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Provider'
}]
},
category: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Category'
}]
},
event: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Event'
}]
},
image: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Image'
}]
},
},
{
toObject: { virtuals: true },
toJSON: { virtuals: true }
},
{
timestamps: true
});
You can use custom validators feature of mongoose.
If the validator function returns undefined or a truthy value, validation succeeds. If it returns falsy (except undefined) or throws an error, validation fails.
product: {
type: [
{
type: Schema.Types.ObjectId,
ref: "Product",
required: true
}
],
validate: {
validator: function(v) {
return v !== null && v.length > 0;
},
message: props => "product is null or empty"
}
}
Now when you don't send product field, or send it empty array it will give validation error.
const notEmpty = function(users){
if(users.length === 0){return false}
else { return true }
}
const EventSchema = new Schema({
product: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Product',
required: true,
validate: [notEmpty, 'Please add at least one']
}]
}
})

How to specify field which is array of objects, objects of array has one of attribute as unique but optional in Mongoose?

This is my schema for employee personal information
const mongoose = require('mongoose');
const PersonalInformationSchema = mongoose.Schema({
name: {
type: String,
required: true
},
emails: [{
email: {
type: String,
trim: true,
unique: true
},
isPrimary: {
type: Boolean
}
}]
}, {
timestamps: true
});
module.exports = mongoose.model('PersonalInformation', PersonalInformationSchema);
In my case I have array emails which is optional for employee but should be unique. When I insert a record without emails, document saves successfully (with empty array emails: []) but in next try it says
"err": {
"driver": true,
"name": "MongoError",
"index": 0,
"code": 11000,
"errmsg": "E11000 duplicate key error collection: EmployeePersonalInformation.personalinformations index: emails.email_1 dup key: { : null }"
}
You can add sparse: true to your schema, try:
const PersonalInformationSchema = mongoose.Schema({
name: {
type: String,
required: true
},
emails: [{
email: {
type: String,
trim: true,
unique: true,
sparse: true
},
isPrimary: {
type: Boolean
}
}]
}, {
timestamps: true
});
The sparse property of an index ensures that the index only contain entries for documents that have the indexed field. The index skips documents that do not have the indexed field.
So when empty documents will be skipped you won't get an error from unique constraint.

Mongoose update Query

Hello All I am attempting to make an update using mongoose and I can't seem to get it working. This is the data that I am saving.
var mongoose = require('mongoose');
var DataSchema = new mongoose.Schema({
advisorEmail: {
type: String
},
data: {
type: Array
},
client: {
type: String,
required: true,
trim: true
},
accountBalance: {
type: Number,
required: true,
trim: true
},
description: {
type: String,
required: true,
trim: true
},
AccountValue: {
type: Number,
required: true,
trim: true
},
moneyMarket: {
type: Number,
required: true,
trim: true
},
buyingPower: {
type: Number,
required: true,
trim: true
},
netBalance: {
type: Number,
required: true,
trim: true
},
advisorPercentage: {
type: Number,
required: true,
trim: true
}
});
var Data = mongoose.model('Table', DataSchema);
module.exports = Data;
Below will be the code I am writing to be able to update the data array
Data.update({
"advisorEmail":"Travis#travis.com"
},
{"$push":
{ "data":{"client": "Tester", "accountBalance": 21342,
"description": "test From Nodejs", "AccountValue": 123234,
"moneyMarket": 11000, "buyingPower": 01, "netBalance": 10,
"advisorPercentage": 24}}}, function(err, updateData){
if (err) throw (err);
console.log(updateData);
});
There are no errors and this is the console.log that I get back from "updateData."
{ ok: 0, n: 0, nModified: 0 }
But when I take the same structure and go into my local mongodb and do
db.tables.update({
"advisorEmail": "Travis#travis.com"
}, {
"$push": {
"data": {
"client": "bobby",
"accountBalance": 123,
"description": "TravisPUTO",
"AccountValue": 123,
"moneyMarket": 1000,
"buyingPower": 0,
"netBalance": 0,
"advisorPercentage": 1
}
}
})
it works completely fine and says this..
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
is this a mongoose issue? I'm not really sure what's wrong.
Thank you for anything you may be able to do to help me!
Please update your schema with additional fields.
advisorEmail : {type: String},
data: { type: Array },
so mongoose identified fields you update.