mongoose unique: true not work [duplicate] - node.js

This question already has answers here:
Unique index in mongoose not working
(1 answer)
Mongoose Unique index not working!
(35 answers)
Closed 8 years ago.
why mongoose unique not work at all in this script
var child_process = require('child_process');
// Load required packages
child_process.exec("mongo test --eval 'db.users.drop();'", function(err){
var mongoose = require('mongoose');
console.log(mongoose.version);
mongoose.connect('mongodb://localhost:27017/test');
// Define our user schema
var json = {};
json.phone = { type: String, required: true, unique: true};
var UserSchema = new mongoose.Schema(json);
var Model = mongoose.model('user', UserSchema);
var jp = new Model({ phone: "123456"});
mongoose.connection.on('open', function(){
console.log(jp);
jp.save(function(err){
console.log(err);
var jp2 = new Model({ phone: "123456"});
console.log(jp2);
jp2.save(function(err){
console.log(err);
process.exit();
});
})
});
});
I'm quite confused, the result is like
3.8.20
{ phone: '123456', _id: 54856cceb5b40f7a88fcc2af }
null
{ phone: '123456', _id: 54856cceb5b40f7a88fcc2b0 }
null
Thank you for your help.

This happens because you're saving the duplicated document before mongoose has finished creating the index. Mongoose creates the indexes on the go, after your app has started.
So, to ensure that your document will be saved only after the indexes were created, you have to listen to the index event of your model. For example:
Model.on('index', function (error) {
console.log(jp);
jp.save(function(err){
console.log(err);
var jp2 = new Model({ phone: "123456"});
console.log(jp2);
jp2.save(function(err){
console.log(err);
process.exit();
});
})
});
Now, when you try to save the second document (the duplicated one), your MongoDB will raise an error, because your save calls will just run after the indexes were created.

Related

Is there a way to edit mongo db sorting?

I have a mongoose collection that sorts by first added, and I want it to sort by last edited
The model
var mongoose = require("mongoose");
var user = require("./user");
var questionSchema = new mongoose.Schema({
text: String,
asked: String,
answer: String
})
module.exports = mongoose.model("question", questionSchema);
The put request code:
router.put("/:user/:id", checkOwner, function(req, res){
question.findByIdAndUpdate(req.params.id, req.body.question, function(err,
updatedQuestion){
if(err) {
console.log(err);
} else {
res.redirect("/");
}
});
});
I want that updatedQuestion to be on the top my collection
Here is one simple approach:
First you have to add timestamps in your mongoose model, in order to have access on createdAt and updatedAt proerties.
You can see more about timestamps here
var mongoose = require("mongoose");
var user = require("./user");
var questionSchema = new mongoose.Schema({
text: String,
asked: String,
answer: String
},
{ timestamps: true}
)
module.exports = mongoose.model("question", questionSchema);
Then you can query your collections, applying sorting by updatedAt
question.find({}, {}, {sort: { 'updatedAt' : -1 }})
Thus the most recent updated document will be shown first.

object referencing/mongoose-mongodb

I have been taking colt Steeles's web development bootcamp classes,so i am on the associations topic. tried writing code to do a one to many association via object referencing, the code appears thus
var mongoose= require("mongoose");
mongoose.connect("mongodb://localhost/blogApp_demo_2",{useNewUrlParser:true});
var postSchema= new mongoose.Schema({
title:String,
content:String
});
var post= mongoose.model("post",postSchema);
var userSchema = new mongoose.Schema({
name: String,
Email:String,
posts:[
{
type:mongoose.Schema.Types.ObjectId,
ref:"post"
}]
});
var user= mongoose.model("user",userSchema);
post.create(
{
title:"beauty in the lilies",
content: "there is so much to marvel in lilies"
}, function(err,post){
user.findOne({email:"deleomoarukhe#yahoo.com"}, function(err,foundUser){
if(err){
console.log(err);
} else{
foundUser.posts.push(post);
foundUser.save(function(err,data){
if(err){
console.log(err);
}else{
console.log(data);
}
});
}
});
});
but on trying to execute this code it gives me this error
TypeError: Cannot read property 'posts' of null
tried everything i can to get this code running, to no avail.
p.s the code was to add a further comment to an already existing user.

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 do I find missing schema fields on a Mongoose query

If I add new fields directly to my MongoDB database and I forget to add them to my Mongoose schema, how can I alert myself to the problem without it failing silently.
The following example shows that all fields are returned from a query (regardless of the schema) but undefined if you access the key.
var mongoose = require('mongoose');
var user_conn = mongoose.createConnection('mongodb://db/user');
var userSchema = mongoose.Schema({
email: String,
// location: String,
admin: Boolean
});
var User = user_conn.model('User', userSchema);
User.findOne({email: 'foo#bar.com.au'}, function (err, doc) {
if (err) return console.log(err);
console.log(doc);
console.log(doc.email);
console.log(doc.location);
});
Result:
{ _id: 57ce17800c6b25d4139d1f95,
email: 'foo#bar.com.au',
location: 'Australia',
admin: true,
__v: 0 } // <-- console.log(doc);
foo#bar.com.au // <-- console.log(doc.email);
undefined // <-- console.log(doc.location);
I could read each doc key and throw an error if undefined, but is this the only way?
Versions
Node.js: 6.5.0
Mongoose: 4.6.0
You can set strict to false on the schema so it will save all properties even if they are not in schema:
var userSchema = mongoose.Schema({
email: String,
admin: Boolean
}, {strict: false});
http://mongoosejs.com/docs/guide.html#strict
In order to get a property which is not in schema you need to use doc.toObject() and use the returned object, or to use doc.get('location')
Following on from Amiram's answer. I now use lean() to get the object during a query but when I need to update or save it still looks up the schema.
User.findOne({email: 'foo#bar.com.au'}).lean().exec(function (err, doc) {
console.log(doc);
console.log(doc.email);
console.log(doc.location);
});

Mongoose save callback doesn't fire

I'm new to mongoose and I'm having a hard time finding the issue within my code. I'm building a REST server using Sails.js and Mongoose. I have a node module (e.g. "sails-mongoose") for exporting mongoose, where I also connect to my database:
var mongoose = require('mongoose');
mongoose.connect('mongodb://#localhost:27017/fooria');
module.exports = mongoose;
And in my model.js:
var adapter = require('sails-mongoose');
var schema = new adapter.Schema({
firstname: {
type: String,
required: true,
trim: true
}
});
module.exports = {
schema: schema,
model: adapter.model('Collection', schema)
}
In my controller's create method I have:
create: function(req, res, next) {
var userData = {firstname: 'Test'};
var users = new Users.model(userData);
users.save(function(err, data){
if (err) return res.json(err, 400);
res.json(data, 201);
});
}
When running create method, the entry is saved to the Mongodb collection but the callback is never reached. Can someone please help me on this track, as I found similar questions but none helped me though. Thanks!
I suppose your are using Express. According Express docs you are calling res.json using incorrect parameters (wrong order).
Correct format:
res.json(code, data)
Example:
res.json(500, { error: 'message' })

Resources