MongoBulkWriteError: E11000 duplicate key error collection - javascript

So, I read all the answers to my problem on Stackoverflow and other websites and none of the solutions have helped me.
The following is the exact error -
MongoBulkWriteError: E11000 duplicate key error collection: test.users index: email_1 dup key: { email: "aaaaaaa#gmail.com" }
Below is my schema -
import mongoose from "mongoose";
const UserSchema = new mongoose.Schema(
{
firstName: {
type: String,
required: true,
min: 2,
max: 50,
},
lastName: {
type: String,
required: true,
min: 2,
max: 50,
},
email: {
type: String,
required: true,
max: 50,
unique: true,
},
password: {
type: String,
required: true,
min: 5,
},
picturePath: {
type: String,
default: "",
},
friends: {
type: Array,
default: [],
},
location: String,
occupation: String,
viewedProfile: Number,
impressions: Number,
},
{
timestamps: true,
}
);
const User = mongoose.model("User", UserSchema);
export default User;
I tried dropping the index email_1 that is causing the problem from the website (graphically).
However, that doesn't seem to do anything. And email_1 is created every time I try to run my server.
Also, I checked my database and found that there is no duplicate 'aaaaaaa#gmail.com' email in my database. I manually uploaded my some starting data to my db for testing purposes of the app I am trying to build.
I am reluctant on deleting my entire database because IF this were to happen to me in production, deleting the entire db would not be an option. I want to fix the issue.
Any help will be appreciated. Thank you.

Right so, I figured out the error.
Whenever you're working with "sample data", make sure you're complying to the restrictions you set in your schema.
In my case, I was trying to add the same sample data to my db every time I ran the server. I essentially forgot to comment out the part of my code where I was inserting my sample data to my db. All I had to do was comment out that part of the code and the server was live again!

Related

Unexpected MongoServerError 11000 (duplicate) for a field that is NOT even declared in schema

I'm developing an online store Node.js REST API with Mongoose (MongoDB), which I'm new to. I decided to test the orders service and saw that after I had made 1 successful order (so it worked once), it sent me a duplicate key error for the next one, for a key 'name' with value 'null', of the order.products collection that is an Array, and not a kvp object.
I should note that nowhere in my code is 'products.name' mentioned.
ERROR:
MongoServerError: E11000 duplicate key error collection: store.orders index: products.name_1 dup
at {...}{
key: { products.name: null }
index: 0,
code: 11000,
keyPattern: { 'products.name': 1 },
keyValue: { 'products.name': null },
[Symbol(errorLabels)]: Set(0) {}
}
when the error is handled, this message is received and it makes no sense:
{ "message": "Order with products.name "null" already exists" }
Order schema:
const schema = new Schema({
userId: {
type: Types.ObjectId,
ref: 'User'
},
address: {
type: addressSchema,
required: true
},
products: {
type: [orderProductSchema],
required: true,
validate: nonEmptyArray
},
status: {
type: Number,
validate: inCollection(Object.values(ORDER_STATUS))
},
price: { type: Number, required: true, min: 0 }
}, { timestamps: true });
don't bother with the validators or the address/status/user/price, it has nothing to do with them; what is more, nothing is specified as unique: true
As you can see, the 'products' field is just an array of products, no 'name' is declared
orderProductSchema:
const schema = new Schema({
product: {
_id: { type: Types.ObjectId, required: true },
name: {
type: String,
required: true,
maxLength: 250
},
displayImage: String,
price: { type: Number, required: true, min: 0 }
},
quantity: {
type: Number,
required: true,
validate: isInteger,
min: 1
},
}, { _id: false });
I have a 'name' field here, but it's just the name of a product. The error is thrown even when the names are unique.
Orders service:
// get data and format it to fit the Order model
console.dir(products); // --> all is how it's expected to be in the schema
return await Order.create({
userId,
address,
products,
status: ORDER_STATUS.AWAITING_CONFIRMATION,
price: totalOrderPrice
});
It seems to me that this is some weird MongoDB behaviour/specification that I missed. If someone has any idea what could cause the problem - please help.
I tried removing all parts such as other fields and validations to see if they might've caused the problem but that was not the case. I thought maybe I had formatted the object I send to the database wrong, but I console.log-ed it and it was fine ({products: Array})
Thanks to #user20042973 and #MTN I saw that my 'orders' database had index 'products.name' (no idea how it got there).. I just removed the index and the problem is solved.

Increment ($inc) update not working with upsert (MongoDB, NodeJS)

I am currently working on a MongoDB Post-Hashtag system, I am using NodeJS and the library "Mongoose". Following the creation of a new "post", I wish to increment the quantity of the "posts" field of the given hashtag's document, else if it does not exist: create a new document for the hashtag. I attempted to do this by utilizing the upsert option and performing a single update (updateOne) for each hashtag. The upserting & new document creation process for a new hashtag appears to work fine, however, pre-existing hashtags do not have their "posts" field incremented.
My code:
await Hashtag.updateOne({hashtag: hashtag}, {
$set: {$inc: {posts: 1}},
$setOnInsert: {
uniqueID: hashtagID,
hashtag: hashtag,
timeOfCreation: now,
posts: 1
}
}, {upsert: true});
I have attempted both with & without the '$set' operator, as well as '$update' and '$inc' to no avail. Omitting it results in the following error:
{
"errorType": "MongoServerError",
"errorMessage": "Updating the path 'posts' would create a conflict at 'posts'",
"code": 40,
"index": 0,
"stack": [
"MongoServerError: Updating the path 'posts' would create a conflict at 'posts'",
...
}
My schema as defined in Mongoose:
const hashtagSchema = new mongoose.Schema({
uniqueID: {
type: String,
required: true
},
hashtag: {
type: String,
required: true
},
timeOfCreation: {
type: Number,
required: true
},
posts: {
type: Number,
required: true
},
});
Remove the $set which is used before $inc.
await Hashtag.updateOne({hashtag: hashtag}, {
$inc: {posts: 1},
$setOnInsert: {
uniqueID: hashtagID,
hashtag: hashtag,
timeOfCreation: now,
posts: 1enter code here
}
}, {upsert: true});

Nodejs app with mongo database tables schema

I want to do a big project API where people can login with Google, send the token and when logged in do some actions saved to Mongo DB.
The problem is the tables structure, or schema. So, I want to do a good app scalable.
I have some tables like Users (with users loggin information) and I want user save his tasks, memories, works and more for him self, and when logged in in another device, get this information and modify.
Do I need to do every table for every user or use same table filtered by user?
For example, I have now this model for product:
const ProductoSchema = Schema({
nameOfProduct: {
type: String,
require: [ true, 'Required name' ],
unique: true
},
state: {
type: Boolean,
default: true,
required: true
},
userOwner: {
type: Schema.Types.ObjectId,
ref: 'Usuario',
required: true
},
priece: {
type: Number,
default: 0
},
category: {
type: Schema.Types.ObjectId,
ref: 'Category',
required: true
},
description: {
type: String
},
disponibility: {
type: Boolean,
default: true
},
img: {
type: String
},
});
Is this correct or this is not scalabe and I need to do all tables for every user?

sort mongodb data based on array express react

i have record in mongoose which kinda look like this(demo) -
{
name:"son",
email:"final#gmail.com",
score:[40,100,30,5]
}
my model is -
const uModel = new Schema({
name: {
type: String,
required: true,
max: 20,
},
email: {
type: String,
required: true,
unique: true,
max: 50,
min: 6
},
password: {
type: String,
required: true,
min: 6
},
profile:{
type: String,
default: ''
},
score:{
type: Array
}})
and here is my post method in express -
const getAllData = (req, res)=>{
userModel.find().sort({score: -1})
.then(user =>{
res.status(200).json(user)
})
.catch(err=>{
res.status(200).json(err)
})}
i have a dashboard and i want to show user with highest score(score is dynamic, changes all the time)
what i want is to sort score array(descending order ) and then sort user based on highest score(descending order). two thing what i want but i have no idea how to do it.
after sorting 0 index of score array should have the higher value and last index lowest.
find().sort({}) does not work for me.
is it possible or should i change my strategy if i should change then what could be better one ??
thanks in advance

How can I display the username of a forum?

I want to find out how I can display the username of a user. For example user admin posts a forum, then I would see Created By: admin on the forum page, instead I can only fish out the ID.
I don't know a much about mongoose and I need someone who is familiar with it.
My Forum Model:
You see I have only ref: 'user' and this is grabbing the ObjectId("") from the User.
const forumSchema = ({
forumName: {
type: String,
required: true,
},
forumDescription: {
type: String,
required: true,
},
user: {
type: Schema.Types.ObjectId,
ref: 'user'
},
published_on: {
type: String,
default: moment().format("LLL")
},
});
my userModel:
const UserSchema = mongoose.Schema({
userID: {
type: String,
required: true,
},
userName: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
isAdministrator: {
type: Boolean,
deafult: false,
},
});
Front-end :
As you can see only in {forum.user} there I can see the id from the user but I want his name not the id
<footer className="blockquote-footer">
Created by:{forum.user}
Created on:{forum.published_on.substring(0,300)}
</footer>
Since you are using 'ref' to reference the user table. When you are fetching a forum document, use the populate() function in mongoose to get all the user details as a sub-object to the forum document.
example: forumShcema.find({_id:<forum_id>}).populate('user').exec()

Categories