This question already has answers here:
MongooseJS cant disable unique to field
(3 answers)
Closed 7 years ago.
My user model looks like:
var UserSchema = new Schema({
name: {
type: String,
unique: false
},
user_url:{
type: String
},
email: {
type: String,
lowercase: true
},
role: {
type: String,
default: 'individual'
},
plan: {
type: String,
default: 'basic'
},
password: String,
provider: String,
salt: String,
facebook: {},
twitter: {},
google: {},
github: {}
});
As you can see, I am trying to allow records with duplicate value in name fields. However when trying to save it throws an error:
Unhandled rejection WriteError({"code":11000,"index":0,"errmsg":"E11000 duplicate key error index: dev.users.$name_1 dup key: { : \"ttp2\" }","op":{"user_url":"ttp2-0","salt":"LY59ooaz+8zZ4z8+dA/7dw==","provider":"local","name":"ttp2","email":"ttp2_1#example.com","password":"wEOc+pejEwfz/s11SWQiMpHxrkh7yLC+q+oa6Tad/QGvH+OFTBMAsVssBRvUKoRjE1dyJkZeh5UvCEJsgXAhNA==","_id":"56b5cc49b6bc872413f6c9fb","__v":0}})
What am I doing wrong?
Presumably, there is still a unique index on the database. If you remove a unique constraint from the mongoose schema which has been defined before, that will not reflect on the database. Simply remove that index directly via the mongodb client.
You can also update your schema programmatically, by putting something like this into your model.js:
mongooseModel.collection.dropIndex('name_of_your_index');
Related
For example if I have this schema
var userSchema = mongoose.Schema({
username: String,
email: String,
password: String,
_todo: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Todo'}]
});
I would like the username to be a unique key that cannot be duplicated by other users. How can I do this?
You can add a constraint with the unique attribute. This will also add a "unique" index for the field to your collection:
var userSchema = mongoose.Schema({
username: { type: String, unique: true },
email: String,
password: String,
_todo: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Todo'}]
});
I came across the same issue. But can't be solved by the accepted answer.
For my example is very simple, just make the name unique.
var FoolSchema = Schema({
name: {
type: String,
unique: true,
index: true,
required: true
}
})
I can save the duplicate name every time.
Then I find this link:
https://mongoosejs.com/docs/faq.html#unique-doesnt-work
The solution is createIndex from mongoDB, not from mongoose.
start mongo shell
mongo, and use yourdbName
run db.foos.getIndexes() (you can't see the "unique" : true, )
db.foos.createIndex( { "name": 1 }, { unique: true } )
try step 2. The results should contains unique.
Hope it could help someone.
EDIT
If your foo table collections contain the duplicated names, you might get error on step 3:
{
"ok" : 0,
"errmsg" : "E11000 duplicate key error collection: mategoal-dev.categories index: name_1 dup key: { : \"TheName\" }",
"code" : 11000,
"codeName" : "DuplicateKey"
}
Then remove all the data or duplicated one(haven't test) first:
db.foos.remove({})
Then try step 3 again.
I want to insert a document in my database from a website form. I have a model created with mongoose and I want to save in the database only the attributes that contains data and I don't want to save empty attributes.
This is my model:
const localizationSchema = new Schema({
name: { type: String, required: true },
spins: [{ type: String }],
spinsForChild: [{ type: String }],
parent: { id: String, name: String },
localizationType: { type: String },
count: { type: Number, default: 0 },
countries: [{ id: String, name: String, cities: [{ id: String, name: String }] }]
});
const Localization = mongoose.model('Localization', localizationSchema);
When I try to save a new document, it creates in the database all attributes although I don't send it on my query.
Localization.create({
name: body.name,
localizationType: body.localizationType,
"parent.id": parent.id,
"parent.name": parent.name,
spins: spins,
spinsForChild: spinsForChild
}, function(err) {
if (err) return handleError(err);
res.redirect('/localizations');
});
This code, for example, inserts in the DB an empty array called "countries".
I tried to use strict: false in the model declaration but it didn't works.
You could use this answer.
But, thing you try to implement seems to be anti-pattern and can cause errors when you will try to use array update operators with undefined array. So, use it carefully.
Good luck!
I have a schema "Questions" it has like a dozen of questions in it, I can add and delete those questions, I need this collection reflected in a field of other collection - "User" with one additional field (nested in options).
Question Schema:
var QuestionScema = new mongoose.Schema({
key: { type: String, required: true },
label: { type: String, required: true },
name: { type: String, required: true },
page: { type: String, required: true },
type: { type: String, required: true },
options: [{
key: {type: String, required: true},
value: {type: String, required: true}
}],
});
User Schema:
var UserSchema = new mongoose.Schema({
Name: { type: String, required: true },
Email: { type: String, required: true, unique: true },
Password: { type: String, required: true },
//this is where I need to reflect a Questions collection on each user,
//so that it will look something like this//
Questions: [{
key: {type: String, required: true},
//here can be all other fields from Questions collection, that is not a problem
options: [{
key: {type: String, reuired: true},
value: {type: String, reuired: true},
counter: {type: Number, default: 0} //this is the additional field
}]
}],
//
Notifications: [{
Title: { type: String },
Data: { type: String },
Created: { type: Date, default: Date.now }
}]
});
I can't figure out how to do that.
I have another collection of users, say User2 that will answer those questions from Questions collections and I need to keep track on Users schema (not User2, there I just save questions and answers) of how many times an option for that question is chosen.
A Questiuons entry can look like this:
{
key: Haveyouseenthismovie,
label: Have you seen this movie?,
name: Have you seen this movie?,
page: 1,
type: dropdown,
options: [{
key: yes,
value: yes
}, {
key: no,
value: no
}]
}
I want it to work like that (reflect a collection in field of each User) so I don't have to check if that question is in User collection if not add and if it is, is there an option that I need if it is than increment, if not than add that option (that user selected from options in that question in Questions schema) and increment. That looks like a bummer. So I figured that it will be better if that field will reflect a collection and I will just increment the option that I need on a question that I need.
Please help me figure that out, I don't have enough practise in mongo so I struggle with it sometimes :)
I don't think there is a way to reflect a collection in another document as the way you seem to wish it.
As I understand, the following options are available for you:
Embed the entire question document inside the User documents in User Collection.
Just maintain the '_id' of the question document in the User document in User Collection.
Please read on Data Modelling concepts & maintaining relationship between documents from Mongo DB Page https://docs.mongodb.com/manual/applications/data-models-relationships/
This question already has answers here:
E11000 duplicate key error index in mongodb mongoose
(22 answers)
Closed 4 years ago.
I am trying to create a blog. I have a user schema, a blog schema, and a comment schema.
When I register a user and create a blog, it works (and saves fine to the database). When I create another user and that user tries to write a blog, I get returned a large error message:
BulkWriteError: E11000 duplicate key error collection: blog.blogs index: username_1 dup key: { : null }
The problem is - there is no key in any of my schema's called username_1. here are my schema's:
var UserSchema = new mongoose.Schema({
firstname: String,
lastname: String,
username: {
type: String,
unique: true
},
email: String,
createdDate: {
type: Date,
default: Date.now()
},
blogs: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Blog"
}
]
});
Blog schema
var BlogSchema = new mongoose.Schema({
title: String,
text: String,
date: {
type: Date,
default: Date.now()
},
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Comment'
}
],
author: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
}
});
The post route is this in case you want to know:
// create a new blog object
var newBlog = new Blog(
{
title : req.body.title,
text : req.body.text,
author: foundUser._id
}
);
// create the new blog
Blog.create(newBlog, function(err, createdBlog) {
if(err) {
console.log(err);
} else {
// push the new blog into the blogs array
foundUser.blogs.push(createdBlog);
// save to db
foundUser.save();
}
});
Actually, I think there is a unique key in your schema.
username: {
type: String,
unique: true
},
Maybe you can try to go though the whole thing with different usernames?
This question already has answers here:
Automatically remove referencing objects on deletion in MongoDB
(8 answers)
Closed 9 years ago.
With MongoDB and Mongoose, How can I mark objects as dependent on their relations so that if the Parent object is deleted, all of the children objects dependent on it will be deleted as well. For instance, how can I have all articles by an author be automatically deleted if the author is deleted?
var AuthorSchema = new Schema({
created: {
type: Date,
default: Date.now
},
name: {
type: String,
default: '',
trim: true
}
});
var ArticleSchema = new Schema({
created: {
type: Date,
default: Date.now
},
title: {
type: String,
default: '',
trim: true
},
content: {
type: String,
default: '',
trim: true
},
author: {
type: Schema.ObjectId,
ref: 'Author'
}
});
If you want to do something like mysql's "foreign key on delete cascade" where if you delete a parent, children are automatically deleted, then it is not possible in pure mongodb.
In order to achieve this, you have to implement it in your application logic. When you delete an author you have to run another delete on the article collection based on the authorID. Do not forget to put an index on this field.