Node.js MongoError: E11000 duplicate key error collection: - node.js

Im working on a djs bot and i ran into an error that i dont know how to fix
i have looked at https://docs.mongodb.com/manual/indexes/ and NodeJs, Mocha and Mongoose
but nothing seems to help here is the info -
the error happens here -
const Data = await serverModel.findOne({ serverID: message.guild.id });
try{
console.log(`checking if a database exists for ${message.guild}`);
console.log(Data);
if(!Data) {
console.log(`Data base doent exist for ${message.guild}`);
console.log(`Creating a database for ${message.guild}`);
const server = await serverModel.create({
serverID: message.guild.id,
calling: 'no',
channel: null,
talkingWith: null,
stickyChannel: null,
stickyMessage: null,
stickyID: null,
});
console.log('shit');
server.save();
return;
}
}
catch(err) {
console.log(err);
}
this is my serverModel/serverSchema -
const mongoose = require('mongoose');
// ServerSchema
const ServerSchema = new mongoose.Schema({
serverID: { type: String, require: true, unique: true, sparse:true },
calling: { type: String, require: true, unique: false, sparse:true },
channel: { type: String, require: true, unique: false, sparse:true },
talkingWith: { type: String, require: true, unique: false, sparse:true },
stickyChannel: { type: String, require: true, unique: false, sparse:true },
stickyMessage: { type: String, require: true, unique: false, sparse:true },
stickyID: { type: String, require: true, unique: false, sparse:true },
});
const model = mongoose.model('ServerSchema', ServerSchema);
module.exports = model;
and lastly this is the error i get -
checking if a database exists for Vixo
null
Data base doent exist for Vixo
Creating a database for Vixo
MongoError: E11000 duplicate key error collection: database.serverschemas index: stickyChannel_1 dup key: { stickyChannel: null }

it seems like there are already records with 'stickyChannel' parameter as null value. So can you please try creating new records by simply assigning values to every parameter?
try following code for creating new record:
`const server = await serverModel.create(
{ serverID: message.guild.id,
calling: 'no',
channel: 'test',
talkingWith: 'test',
stickyChannel: 'test,
stickyMessage: 'test,
stickyID: 'test',
});`

Related

Unable to Get Data from Secondary Collection MERN

I have a user Full stack tool, and i've separated the users into 'users' and 'companyusers' respectively within my backend.
Within this, I have a fully fuctioning GET for users, which looks like this:
router.get("/findUser/:id", async (req,res)=>{
try{
const user = await User.findById(req.params.id)
const { password, ...others } = user._doc;
res.status(200).json(others);
}catch(err){
res.status(500).json(err)
}
})
Pretty generic, but it works.
I've created the schema:
const mongoose = require("mongoose")
//CompanyProfileSchema
const CompanyProfileSchema = new mongoose.Schema(
{
companyTitle:{type:String, required: true, unique: true, default: ""},
companyPassword:{type:String, required: true, default: ""},
centralEmail:{type:String, required: true, unique: true, default: ""},
description:{type:String, required: true, default: ""},
industry:{type:String, required: true},
employees:{type: Number},
companyImage: {type:String, required: false, unique: false, default: ""},
locationCity:{type:String, required: false, unique: false, default: ""},
industry:{type:String, required: false, unique: false, default: ""},
country:{type:String, required: false, unique: false, default: ""},
highlights: {type: Array},
isAdmin:{
type: Boolean,
default: false,
},
isVerified:{
type: Boolean,
default: false,
},
invitedUsers: {type: Array}
},
);
module.exports = mongoose.model("CompanyUser", CompanyProfileSchema)
Which works and is in the index.js as such
app.use("/api/users", userRoute)
app.use("/api/companyprofile", companyprofileRoute)
However, in my companyprofile request file, when I complete the request, I am getting empty data back:
const CompanyProfile = require("../models/CompanyProfile");
const { route } = require("./auth");
router.get("/findCompany/:id", async (req,res)=>{
try{
const companyUser = await CompanyProfile.findById(req.params.id)
res.status(200).json(req.params.body);
const { password, ...others } = companyUser._doc;
// res.status(200).json({others});
}catch(err){
res.status(500).json(err)
}
})
This is with a request like:
localhost:5000/api/companyprofile/findCompany/61f2980a7d4bb550edf8ec7e
and a body of
{
"centralEmail": "natia1#bank.com.au"
}
Any ideas?

How to properly use references in mongoose

I am trying to use references in mongoose but somehow am not being able to do it properly.
What I am trying to achieve
I would like to query the examModel and get all information about a particular exam including the questions related to that exam.
What I achieved
New questions get saved into the questionModel with the object id of the exam am saving the question for, BUT, the questions array of the examModel doesnt take notice of it.
I have two different models:
examModel
const examSchema = new mongoose.Schema({
examId: {
type: String,
unique: true,
index: true,
required: true,
default: _generateAlphanumericId(18),
},
questions: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Questions",
}],
}, {
timestamps: true,
});
module.exports = mongoose.model("Exams", examSchema);
questionModel
const questionSchema = new mongoose.Schema({
_refExamId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Exams",
},
questionId: {
type: String,
unique: true,
index: true,
required: true,
default: _generateAlphanumericId(26),
},
title: {
type: String,
trim: true,
required: [true, "Question is missing"],
},
}, {
timestamps: true,
});
module.exports = mongoose.model("Questions", questionSchema);
Now, when I save a new question into the question model, I am sending the _id of an exam from the exam model but still the questions array of exam model doesnt save the object ids of newly created questions.
How I am creating a new question
try {
const question = new questionModel({ _refExamId: req.body._refExamId, title: req.body.title });
await question.save();
return res.status(200).json({ type: "SUCCESS" });
}
catch (error) {
return res.status(500).json({
type: "ERROR",
message: "Some unknown error occurred",
});
}
try {
const question = new questionModel({ _refExamId: req.body._refExamId, title: req.body.title });
const saved_question = await question.save();
const getExam = await examModel.find({_id: saved_question._refExamId});
getExam.questions.push(saved_question._id);
const result = await getExam.save();
return res.status(200).json({ type: "SUCCESS" });
}catch (error) {
return res.status(500).json({
type: "ERROR",
message: "Some unknown error occurred",
});
}
This should get it working.
First of all,
Exam Model
const examSchema = new mongoose.Schema({
examId: {
type: String,
unique: true,
index: true,
required: true,
default: _generateAlphanumericId(18),
},
questions: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Question'
}],
}, {
timestamps: true,
});
module.exports = mongoose.model("Exam", examSchema);
Note: I turned Exams to Exam, Mongodb will change it to plural on your DB
Question Model
const questionSchema = new mongoose.Schema({
_refExamId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Exam",
},
questionId: {
type: String,
unique: true,
index: true,
required: true,
default: _generateAlphanumericId(26),
},
title: {
type: String,
trim: true,
required: [true, "Question is missing"],
},
}, {
timestamps: true,
});
module.exports = mongoose.model("Question", questionSchema);
Note: I turned Questions to Question, Mongodb will change it to plural on your DB
Creating a new Question
try {
const question = new questionModel({ _refExamId: req.body._refExamId, title: req.body.title });
await question.save();
return res.status(200).json({ type: "SUCCESS" });
}
catch (error) {
return res.status(500).json({
type: "ERROR",
message: "Some unknown error occurred",
});
}
Try that and lets see
So, I was not reading the refs-to-children part of the docs where it states that, there will be no references in the parent schema unless we explicitly push the reference to the parent.
As a result the following solved my issue:
try {
const exam = await examModel.findOne({ examId: req.body.exam_id });
const question = new questionModel({ title: req.body.title, positiveMarks: req.body.positiveMarks });
exam.questions.push(question);
await exam.save(question.save());
return res.status(200).json({ type: "SUCCESS" });
}
catch (error) {
return res.status(500).json({
type: "ERROR",
message: "Some unknown error occurred",
});
}

Mongoose: How to unselect a field & still use it to calculate a virtual

So I'm learning mongodb & mongoose, and I'm trying to make a projects/tasks app
this is the ProjectModel:
const projectSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
unique: true,
trim: true,
lowercase: true,
},
grp: {
type: String,
required: true,
trim: true,
lowercase: true,
},
tasks: {
type: [taskSchema],
},
createdAt: { type: Date, default: Date.now },
},
{
toObject: { virtuals: true },
toJSON: { virtuals: true },
}
);
projectSchema.virtual('tasksCount').get(function () {
return this.tasks.length;
});
And when requesting the data, this runs :
getAllProjects = async (req, res) => {
try {
const query = await Project.find().select({tasks: -1});
const projects = query.;
console.log(projects);
res.status(200).send({
status: 'sucess',
data: {
projects,
},
});
} catch (error) {
res.status(400).send({
status: 'fail',
msg: `error info : ${error}`,
});
}
};
The problem is : I get this error: TypeError: Cannot read property 'length' of undefined.
Its coming from the virtual property ('tasksCount'), So it seems when I unselect the ('tasks') property the virtual one can't be calculated, I hope someone have a way to unselect 'tasks' and still be able to send 'tasksCount'.
You can follow this code
const query = await Project.find().select("-tasks");

Make Mongoose property no longer unique

Im getting a bizarre error with Mongoose. When a user registers they give the name of the organisation they belong to. Previously, this needed to be unique. My schema was:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Organisation = new mongoose.Schema({
name: {
type: String,
required: true,
unique: true
},
createdById: {
type: Schema.Types.ObjectId,
ref: 'User'
},
createdOn: {
type: Date,
"default": Date.now
},
availableUntil: {
type: Date
}
});
Organisation.path('name').validate(function(value, done) {
var self = this;
if (!self.isNew) {
return done(true);
} else {
//mongoose.models['Organisation'] or self.model('Organisation')
mongoose.models['Organisation'].count({
name: value
}, function(err, count) {
if (err) {
return done(err);
}
return done(!count)
});
}
}, "This email already exists");
mongoose.model('Organisation', Organisation);
But now it doesn't matter, an organisation name doesn't need to be unique. So I changed to:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Organisation = new mongoose.Schema({
name: {
type: String,
required: true
},
createdById: {
type: Schema.Types.ObjectId,
ref: 'User'
},
createdOn: {
type: Date,
"default": Date.now
},
availableUntil: {
type: Date
}
});
mongoose.model('Organisation', Organisation);
Note how unique: true has been removed.
I've restarted the server but bizarrely, I still get the error:
name: 'MongoError',
message: 'E11000 duplicate key error index: redmatter.organisations.$name_1 dup key: { : "delete me" }',
driver: true,
code: 11000,
index: 0,
errmsg: 'E11000 duplicate key error index: redmatter.organisations.$name_1 dup key: { : "delete me" }',
getOperation: [Function],
toJSON: [Function],
toString: [Function] }
How is this possible? Why am I getting a duplicate key error when I don't care if the name is not unique?

Sails js one to one populate conditions not working?

I'm newbie of Sails and I've got a problem with one to one association.
First, I have model User:
module.exports = {
schema: true,
identity : "User",
tableName: "user",
attributes: {
email: {
type: 'email',
unique: true,
required: true
},
password: {
type: 'string'
},
salt: {
type: 'string'
},
merchant: {
model: 'merchant',
defaultsTo: null
},
removed: {
type: 'boolean',
required: true,
defaultsTo: false
}
}
}
And my Merchant model:
module.exports = {
schema: true,
identity : "Merchant",
tableName: "merchant",
attributes: {
name: {
type: 'string',
unique: true,
required: true
},
code: {
type: 'string',
unique: true,
required: true
},
security_key: {
type: 'string',
required: true
},
active: {
type: 'boolean',
defaultsTo: false,
required: true
},
user: {
model: 'user'
}
}
}
So when I need to find records where merchant.active = true, I write this query:
var findUser = User.find(query).populate('merchant', {active: true});
return findUser;
But it was not working at all.
Anyone any ideas to solve this properly?
P.S. my Sails version is: 0.11.1. My DB is MongoDB
First of all, remove defaultsTo from your association attributes. I don't like this :) I don't know if it makes the problem, but in documentation I never see this.
Also you need to execute your query, not just return it. If I take your models' declarations then I can write populate query like this.
var findUser = User.find(query).populate('merchant', {active: true});
findUser.then(function(user) {
console.log('Your user is ' + user);
}).catch(function(error) {
console.log('Your error is ' + error);
});

Resources