Maximum call stack exceeded mongoose - node.js

I'm trying to save documents into a mongodb collection using mongoose/node.js with the schema ,
var userSchema = {
userName : String,
userId : Number,
Location : [{Country : String}]
};
var mySchema = {
userData : userSchema,
title : String
};
var MyModel = mongoose.model('MyModel' , mySchema);
However on ,
req.MY_user = JSON.parse(res.body); // Response from an API
MyModel.update({title : 'sometitle'} , {userData : req.MY_user , title : 'sometitle'} ,
{upsert : true} ,
function(err , raw){ ... });
I get an error, Maximum call stack exceeded.
Strangely, it works fine on my local machine running Mac.
Problem arises when deployed to linux/windows.
Any solutions please ?
Eg Response :
req.MY_user = {
userName : 'John',
userId : 12345,
Location : [{Country : 'Rus'} , {Country : 'Ind'}]};
Update , adding error.stack,
Range Error : at Function.isArray (native),
at shouldFlatten node_modules/mongoose/lib/services/common.js 81:13
at modifiedPaths node_modules/mongoose/lib/services/common.js 65:7
(above line is repeated multiple times)

Related

How do I prevent a field update in moongoose

I have a schema that looks like this :
"use strict"
const mongoose = require('mongoose');
const timestamp = require('mongoose-timestamp');
const CustomerSchema = new mongoose.Schema({
name : {
type : String,
required : true,
trim : true
},
email : {
type : String,
required : true,
trim : true
},
balance : {
type : Number ,
default : 0
}
})
//use timestamps to add created at and updated at
CustomerSchema.plugin(timestamp);
const Customer = mongoose.model('Customer',CustomerSchema);
module.exports = Customer;
When I want to run an update , I run this code
const Customer = require('../models/Customer');
const customer = await Customer.findOneAndUpdate({_id : req.params.id}, req.body);
so req.body carries the data that will be updated
The problem is that I do not want people to update the email field .
So my question is :
How do I lock the email field from being updated . Is there a way to lock it in the schema , so that it can only be added initially but not updated later ?
Thanks .
There is a property you can define at the schema level called immutable.
Reference to documentation: https://mongoosejs.com/docs/api/schematype.html#schematype_SchemaType-immutable
So your schema would look like this:
const CustomerSchema = new mongoose.Schema({
name : {
type : String,
required : true,
trim : true
},
email : {
type : String,
required : true,
trim : true,
immutable: true // ADD THIS PROPERTY HERE
},
balance : {
type : Number ,
default : 0
}
}
There is no functionality to prevent from update
You can do by removing email object from body
delete req.body.email;
const customer = await Customer.findOneAndUpdate({_id : req.params.id}, req.body);

Mongoose:Some fields are missing while printing user on console in mongodb

I have a problem when I am trying to print user on the server console
my code is
var user = new User({userid:userid})
console.log(user)
its printing on the console
{ userid: 'qq', questions: [], _id: 5ad4602efb255e054412acfa }
but in my database I have saved user like this
{ "_id" : ObjectId("5ad4602efb255e054412acfa"), "id" : 0, "userid" : "qq", "password" : "$2a$10$NNqsVSoTs7eWJiLWy0fZN.0P2mMiiYFYRDFVaLJA9fcY53xRM3uLK", "questions" : [ ], "__v" : 0 }
I have five fields in my database
1-_id,
2-id,
3-userid,
4-password,
5-questions[]. But when I am trying to print user on the console its not printing some fields...why?
my schema is
var mongoose = require("../../connection");
var Schema = mongoose.Schema;
var userSchema = new Schema({id:Number,
userid:String,
password:String,
questions:[]
});
var User = mongoose.model("onlineusers",userSchema);
module.exports = User;
and also when I am trying to print console.log(user.id)
its print undefined

Why the callback in mongoose code getting document as null?

I have following code:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test')
var Schema = mongoose.Schema;
var schema = new Schema({name : String, inventory: {}});
var Character = mongoose.model('Character',schema);
var Frodo = new Character({name: 'Frodo',inventory:{ringOfPower: 1}});
Frodo.save();
Character.findOne({name : 'Frodo'},function(error, character){
console.log(character);
});
I am running it as node optionminimize.js and null is getting logged to the console.It got persisted in mongodb alright, I opened a mongodb shell and ran
db.characters.findOne({name:'Frodo'})
and get following result:
{
"_id" : ObjectId("582fc3bab386f00ed0e7fede"),
"name" : "Frodo",
"inventory" : {
"ringOfPower" : 1
},
"__v" : 0
}
Why the document parameter in the callback is receiving null?
Frodo.save() is a async call so it returns a Promise, and you search by Charachter.findOne immediately the line after which happens before the Frodo.save() promise is resolved.
So, the search must be executed after the character is saved successfully, otherwise it returns null as you mentioned, so your code need to be like this:
Frodo.save()
.then(function() {
Character.findOne({name : 'Frodo'}, function(error, character) {
console.log(character);
});
})

Mongoose mapReduce Error: OUT parameter must be defined

I am using mongoose framework to communicate with the mongodb. Now i am in the situation to join the two collections using mapReduce. I have followed this tutoria "http://blog.knoldus.com/2014/03/12/easiest-way-to-implement-joins-in-mongodb-2-4/" to get it done.
I have successfully done with join using mapReduce in mongoDB Shell using robomongo.
Same i am trying with mongoose frame work but its giving me error that Out parameter must be defied.
The code sample what i have done.
This is the collection schema for User profile:
var User = new mongoose.Schema({
name : {
first : {type : String},
last : {type : String}
},
title : {type : String},
userName : {type : String, unique : true},
profileImgUrl : {type : String},
mojo : Number
});
this is the collection schema for the testimonials:
var Testimonials = new mongoose.Schema({
from : String,
to : String,
text : String
});
This is the code using mongoose, nodejs:-
var mapTalent = function () {
var output= {userName : this.userName,firstname:this.name.first, lastname:this.name.last , profileImgUrl : this.profileImgUrl, mojo : this.mojo, text : null}
emit(this.userName, output);
};
var mapTestimonial = function () {
var output = {fromTalentName : this.fromTalentName, firstname:null, lastname:null, profileImgUrl : null, mojo : null, text : this.text}
emit(this.text, output);
};
var reduceF = function(key, values) {
var outs = {firstname:null, lastname:null , profileImgUrl:null, text : null, mojo:null};
values.forEach(function(v){
if(outs.firstname ==null){
outs.firstname = v.firstname
}
if(outs.lastname ==null){
outs.lastname = v.lastname
}
if(outs.profileImgUrl ==null){
outs.profileImgUrl = v.profileImgUrl
}
if(outs.mojo ==null){
outs.mojo = v.mojo
}
if(outs.text == null){
outs.text = v.text
}
});
return outs;
};
result = Testimonials.mapReduce(mapTestimonial, reduceF, {out : {reduce : "Talent_Testimonials"}});
result = Talent.mapReduce(mapTalent, reduceF, {out : {reduce : "Talent_Testimonials"}});
Here the error is thrown as " the out option parameter must be defined".
What i am doing wrong here i am not getting. This same works in mongoDB shell.
mapReduce can't be called the same way in Mongoose as it is in the shell.
For Mongoose, the call would need to look like:
Testimonials.mapReduce({
map: mapTestimonial,
reduce: reduceF,
out : {reduce : "Talent_Testimonials"}
}, function (err, results) { ... });
See the docs here.

Node.js - How to create a unique id with mongoose db

I am working with Twitter authentication and want to store the twitter id as unique key in mongodb. However i see multiple entries with the same id. Here's my schema and code
Schema:
var TwitterSchema = new Schema({
accessToken: String,
accessTokenSecret: String,
name: String,
twitterId: { type: String, required: true, index: { unique: true, sparse: true } }
});
Code:
mongoose.connect('mongodb://localhost/twd')
mongoose.model('Post', TwitterSchema);
var Post = mongoose.model('Post');
var post = new Post();
post.accessToken = accessToken
post.accessTokenSecret = accessTokenSecret
post.name = twitterUserData.name
post.twitterId = twitterUserData.id
post.save(function(err){
if (err){
throw err;
promise.fail(err);
}
console.log('saved');
mongoose.disconnect();
});
promise.fulfill(post);
DB shell output
> db.posts.find();
{ "twitterId" : "21475255", "name" : "MMMK", "accessTokenSecret" : "ZYhiXMWfXvSr1aaCB93hgU243j8aapP0ALdSFlWEE", "accessToken" : "22475255-9YvKMceUInUIxcEtKAK0oMRRG2ZZxn5c52vnwPw", "_id" : ObjectId("4feddf6155203990e000001") }
{ "twitterId" : "21475255", "name" : "MMMK, "accessTokenSecret" : "ZYhiXMWfXvSr1aaCB93hgU2438aapP0ALdSFlWEE", "accessToken" : "22475255-9YvKMceUInUIxcEtKAK0oMRRG2ZZxn5c52vnwPw", "_id" : ObjectId("4feddf7b5905a1a10e000001") }
My guess is either the index isn't being created in MongoDB, or the index with the same name already exits. If it already exists, mongoose will use ensureIndex to create it, but that won't override/redefine it if it already exists. Use the mongo js shell to see if it exists, then try dropping it, restarting mongod, and running your node.js code again.
http://www.mongodb.org/display/DOCS/Indexes#Indexes-CreationOptions

Resources