MongoError: E11000 duplicate key error - node.js

i'm making a simple blog app using nodejs + express, i can add first post without a problem but when i try to add second post i got his error { MongoError: E11000 duplicate key error collection: restful_blog_app_v2.blogs index: username_1 dup key: { : null }
this is my schema
var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var BlogSchema = new mongoose.Schema({
title: String,
image: String,
body: String,
created: {
type: Date,
default: Date.now
},
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String
}
});
BlogSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("Blog", BlogSchema);
this is the user schema
var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var UserSchema = new mongoose.Schema({
username: String,
password: String,
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSchema);
this is the create new post route
app.post("/blogs", isLoggedIn, function (req, res) {
req.body.blog.body = req.sanitize(req.body.blog.body);
var title = req.body.blog.title;
var image = req.body.blog.image
var body = req.body.blog.body;
var created = req.body.blog.created;
var author = {
id: req.user._id,
username: req.user.username
}
var newPost = {
title: title,
image: image,
body: body,
created: created,
author: author
}
Blog.create(newPost, function (err, newBlog) {
if (err) {
console.log(err);
res.render("new");
} else {
console.log(newBlog);
res.redirect("/blogs");
}
});
});
I've tried to dropped the entire database using db.dropDatabase() from the mongo console but the problem still persist, not sure what to do now

This is caused by passport-local-mongoose, which, according to its fine manual, makes username a unique field by default.
You have added this plugin to BlogSchema, which seems like you initially had the user data in that schema but moved it to a separate schema (UserSchema) and forgot to remove it from the former.
Start by not using it for BlogSchema, and you also need to drop the unique index on username on the blogs collection.

Can you try deleting your Schema and again send the value? I was getting the same issues. I solved with the above idea.

Related

mongoose db populate doesn't seem to work

So this is how my models are:
groupModel.js
var Schema = mongoose.Schema;
var groupSchema = new Schema({
uuid: String,
users: [{type: Schema.Types.ObjectId, ref:'users'}]
});
var Groups = mongoose.model('groups', groupSchema);
module.exports = Groups;
userModel.js
var mongoose = require('mongoose')
var Schema = mongoose.Schema;
var userSchema = new Schema({
username: String,
password: String,
firstname: String,
lastname: String,
email: String,
emailVerified: Boolean
});
var Users = mongoose.model('users', userSchema);
module.exports = Users;
and this is the api I am hoping to get it to work:
/* GET /group/list/:id listing. */
router.get('/list/:id', function(req, res) {
Group.findOne({uuid :
req.params.id}).populate('Users').exec(function(err, group){
if(err) throw err;
console.log(group);
res.status(200).send(group);
});
});
this is the response I get back:
{"_id":"5aaf52b4165e97aae4a0b42c","uuid":"iyzIc","__v":0,"users":
["58f5acae4733ae5f64XXXXea","590a663c2a32ad28e0XXXX29"]}
For some reason I am not able to replace the id's with actual data for the users. I was hoping to get user related details instead of ids for the two users. Am I doing something wrong? I am trying to learn nodejs and was hoping some nodejs expert will be able to find my silly mistake.
EDITED:
changing .populate('Users') -> .populate('users') fixed the issue.
Users being capitalized in populate is the problem!

MongoDB : Missing the key _id in the item

I have been given some code to modify. It is a Node.js app using Mongoose to interact with a MongoDb instance. In Mongoose several schemas were already set up and I've added a few. Among those are these two schemas which break apart a previously existing schema (which was working fine with small data):
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var MapConvertedProjectSchema = new Schema(
{
project_id : {
type: String,
default: ""
},
dataset_id : {
type: String,
default: ""
},
properties:{
type: {},
default: {}
}
});
MapConvertedProjectSchema.pre('save', function(next) {
next();
});
mongoose.model('MapConvertedProject', MapConvertedProjectSchema);
and
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var MapConvertedLayerSchema = new Schema(
{
parent_id:
{
type: mongoose.Schema.Types.ObjectId
},
class:
{
type: String,
default: 'MapLayer',
trim: true
},
properties:
{
type: {},
default: {}
}
});
//Hook a pre save method to clean date
MapConvertedLayerSchema.pre('save', function(next) {
next();
});
mongoose.model('MapConvertedLayer', MapConvertedLayerSchema);
I use the MapConvertedLayer schema like so:
var mongoose = require('mongoose');
var LayerConverted = mongoose.model('MapConvertedLayer');
var newLayer = new LayerConverted();
//newLayer._id is automatically populated with a value
//... add other properties
newLayer.save(function(err)
{
if(err)
{
//...
}
});
This works without any issues that I can discern. However if I try similar code with MapConvertedProject I get an error:
var mongoose = require('mongoose');
var ProjectConverted = mongoose.model('MapConvertedProject');
var map_converted = new ProjectConverted();
//map_converted._id is undefined
//I tried adding the comment below to create an _id manually, but it didn't make a difference when I tried to save
//map_converted._id = mongoose.Types.ObjectId();
console.log("Project Converted ID: " + map_converted._id);
//... fill out the other properties on the schema
map_converted.save(function(err)
{
if(err)
{
//...
}
});
The save generates this error:
ValidationException: One or more parameter values were invalid: Missing the key _id in the item
Does anyone know what is causing this?
I figured this out. There was another place in the code that had a dynamoose model with the same name that was messing things up. I was able to remove all references to dynamoose since it doesn't appear to be used anymore and that cleared up this issue.

How to associate the ObjectId of the parent schema to the child schema in the same transaction?

I have two types of entities, users and families, with a many-to-one relationship between families and users, so one family can have many users but one user will only have one family. I attempted to create a Mongo schema that tries to achieve this relationship, but not sure if this is the right way to do it.
I have a button on my HTML page that when clicked, will generate a family code and also create a new family attribute for the family entity. However, I'm unable to connect that newly generated family.ObjectId to the user's familyid attribute in the user entity.
Any idea what I'm doing wrong?
My Models:
Family Model:
var mongoose = require("mongoose");
var shortid = require('shortid');
//Set Schema
var familySchema = mongoose.Schema({
individuals: [{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
}],
familyCode: {
type: String,
'default': shortid.generate
}
});
//setup and export the model
module.exports = mongoose.model("Family", familySchema);
Users Model:
var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var UserSchema = new mongoose.Schema({
username: String,
password: String,
image: String,
firstName: String,
lastName: String,
accountid: String,
isAdmin: {type: Boolean, default: false},
userlabel: String,
familyid:
{ type : mongoose.Schema.Types.ObjectId,
ref: "Family"}
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSchema);
My Route:
router.post("/familySetup", function(req, res){
if(!req.body.familyid){
var familyCode = shortid.generate();
console.log(familyCode);
// var individuals = {id:req.user._id}
var newFamily = {familyCode:familyCode};
Family.create(newFamily, function(err, newFamily){
if(err){
req.flash("error", "something seems to have gone amiss. Please try again.")
console.log(err);
res.redirect("home")
}else{
var updatedUser = {familyid:newFamily._id}
console.log(updatedUser);
User.findByIdAndUpdate(req.params.user_id, updatedUser, function(req, res){
if(err){
console.log(err);
}else{
//redirect to index
res.redirect("/familySetup");
}
});
}
});
}else{
alert("You already have a family account");
res.redirect("back");
}
});
Based on the error I get, I am able to create a familyCode and am able to create the variable, updatedUser. But it does not update the user with the new attribute. This is the error when I run the code:
ByJyRqb_Z
{ familyid: 59941dd6589f9a1c14a36550 }
events.js:141
throw er; // Unhandled 'error' event
^
TypeError: Cannot read property 'redirect' of null
at /home/ubuntu/workspace/mbswalay/routes/family.js:44:28
at Query.<anonymous> (/home/ubuntu/workspace/mbswalay/node_modules/mongoose/lib/model.js:3755:16)
at /home/ubuntu/workspace/mbswalay/node_modules/mongoose/node_modules/kareem/index.js:277:21
at /home/ubuntu/workspace/mbswalay/node_modules/mongoose/node_modules/kareem/index.js:131:16
at nextTickCallbackWith0Args (node.js:436:9)
at process._tickCallback (node.js:365:13)
It doesn't seem to be an error of mongodb, it's related to the route configuration, which seems make the response object to be null
User.updateOne(
{ _id: req.params.user_id },
{ $set: { familyid: newFamily._id } }
)
You have to set the value of an attribute using $set operator.

Mongoose - inserting subdocuments

I have a user model, and a log model. The log model is a subdocument of user model. So in my user model I have:
var mongoose = require('mongoose');
var Log = require('../models/log');
var UserSchema = new mongoose.Schema({
username: {
type: String,
unique: true
},
logsHeld: [
Log
]
});
Then in my 'Log' model I have:
var mongoose = require('mongoose');
var logSchema = new mongoose.Schema({
logComment: {
type: String,
},
});
module.exports = mongoose.model('Log', logSchema);
So upon creation of a 'user', the 'logsHeld' always begins empty. I want to know how to add subdocuments to this user model.
I've tried doing this POST method:
router.post('/createNewLog', function(req, res) {
var user = new User ({
logssHeld: [{
logComment: req.body.logComment
}]
});
user.save(function(err) {
if(err) {
req.flash('error', 'Log was not added due to error');
return res.redirect('/home');
} else {
req.flash('success', 'Log was successfully added!');
return res.redirect('/home');
}
});
});
But this doesn't work. It also includes a 'new User' line, which I don't think I need given this would be for an existing user.
You need to use the logSchema instead of the Log model as your subdocument schema in User model. You can access the schema as follows:
var mongoose = require('mongoose');
/* access the Log schema via its Model.schema property */
var LogSchema = require('../models/log').schema; // <-- access the schema with this
var UserSchema = new mongoose.Schema({
username: {
type: String,
unique: true
},
logsHeld: [LogSchema]
});
Picking up from your comments in another answer where you are facing another issue
WriteError({"code":11000,"index":0,"errmsg":"E11000 duplicate key
error index: testDB.users.$email_1 dup key:
you are getting this because there's already a document in your users collection that has most probably a null value on the email field. Even though your schema does not explicitly specify an email field, you may have an existing old and unused unique index on users.email.
You can confirm this with
testDB.users.getIndexes()
If that is the case and manually remove the unwanted index with
testDB.users.dropIndex(<index_name_as_specified_above>)
and carry on with the POST to see if that has rectified the error, I bet my $0.02 that there is an old unused unique index in your users collection which is the main issue.
Try using logSchema which references only the subdocument schema, Log refers to the entire contents of ../models/log
var UserSchema = new mongoose.Schema({
username: {
type: String,
unique: true
},
logsHeld: [
logSchema
]
});
Documentation: http://mongoosejs.com/docs/subdocs.html
Try push to insert item in array in mongoose
var user = new User;
user.logssHeld.push({
logComment: req.body.logComment
});
user.save(function(err, doc) {
//DO whatever you want
});
see the docs here

How to get data from existing MongoDB database?

I have a database on mlab and now I was starting a new Project and trying to simply get data from there.
The Database has only one collection called Article.
On my Node js project, using Mongoose, I created the Model for it:
var mongoose = require('mongoose');
var articleSchema = new mongoose.Schema({
title: { type: String, required: true },
body: { type: String }
});
var Article = mongoose.model('Article', articleSchema);
module.exports = Article;
The in my controller I just did this:
Article.find({}, function (err, articles) {
res.send(articles);
});
I should receive more than 300 articles but the response is just an empty Array.
I was wondering if I need to run a few more command in order to connect to the db correctly, but I don't know it...
If you want to fetch on an existing Article collection:
var articleSchema = new mongoose.Schema({
title: { type: String, required: true },
body: { type: String }
}, { collection : 'Article' });

Resources