Mongoose retrieval of info from multiple collections - mongodb

I'm building a resume building app with Mongoose and Express. I set my models up so that education and work experience are both in their own collections. something similar to this:
"degree" : "BA",
"major" : "Econ",
"minor" : "Bus. Admin",
"startDate" : ISODate("2013-12-31T00:00:00Z"),
"endDate" : ISODate("2013-01-01T00:00:00Z"),
"user" : "example#gmail.com",
"created" : ISODate("2013-10-15T19:32:09.357Z"),
"_id" : ObjectId("525d9839ddc8bf7855000001"),
"school" : {
"name" : "university of alabama",
"loc" : "austin, tx"
},
"__v" : 0
I have a reference to the _id of the User model in the "user" value. my User model looks like so:
var schema = mongoose.Schema({
_id: {type: String, lowercase: true, trim: true, validate: validEmail }
, name: { first: String, last: String}
, salt: {type: String, required: true}
, hash: {type: String, required: true}
, edu: [{type: String, ref: 'Education'}] });
When I try to populate the edu section of my User model with information from the education model it's not finding anything.
My query is this:
var query = User.findById(user)
.populate('edu');
So how would I properly allow my User model make references to the education model so that I can send info from both to a view? Could I populate to fields like that?
Any advice would be mega helpful. I'll be scouring the docs, google and trying random things that kind of make sense in the mean time.
Thank you.

You need to use the mongoose.Schema.Types.ObjectId type in order for populate to work properly.
var schema = mongoose.Schema({
_id: {type: String, lowercase: true, trim: true, validate: validEmail }
, name: {first: String, last: String}
, salt: {type: String, required: true}
, hash: {type: String, required: true}
, edu: [{type: mongoose.Schema.Types.ObjectId, ref: 'Education'}] });
side note:
you don't need to define _id as you get that automatically and it should not be an email. Use a separate email field for that.

Related

How to query results from multiple tables in mongoose?

I have two tables
let SalesItemsSchema = new Schema({
name: {type: String, required: true},
quantity : {type:Number , required:true},
sale_id: {type: String, required: true},
amount : {type:Number , required:true},
purchase_amount : {type:Number , required:true},
} , {timestamps : true});
let InventorySchema = new Schema({
name: {type: String, required: true, max: 100},
quantity: {type: Number, required: true},
} , {timestamps:true});
I want to get the remaining items in the inventory. For example 100 items of something were added to the inventory and 90 of them were sold.
i want to get the difference from two tables (which will be 10)
i am using mongoose.

How can I add a unique auto increment ID inside mongoDB object

I have a table users. This is the schema.
var usersSchema = mongoose.Schema({
uname : {type : String , unique: true},
email : {type : String},
logintype : {type : String},
password : String,
status : String,
hash : String,
social: {},
games: Object,
os: String,
friends: Object,
msges:Object
});
The msges are objects. But what I want is to have key value pair inside msges. So what I did was
function sendMsgToFriend(uname,friendUname,title,msg,time,callback){
global.users.find({"uname":friendUname},
function(err,doc){
if(err){
callback(false,err,"Msg cannot be sent");
}else{
global.users.update( {"uname" : uname},
{
$addToSet : {
"msges":{time:{"from":uname,"title":title,"msg":msg,"read":false}}
}
},function(err,doc){
if(err){
callback(false,err,"Msg cannot be sent");
}else{
callback(true,null,"Msg has been sent");
}
}
);
}
}
);
}
I tried to make 'time' the key and rest its value. But what happened was that instead of value of time, string "time" appeared. Can I make an auto increment Key of msges? Thankyou in advance.
You define "msgs" as a object but what i read from your question is you want a array of objects..
Why don't you create a model for messages and make make "msgs" an array of references to that object.
var usersSchema = mongoose.Schema({
uname : {type : String , unique: true},
email : {type : String},
logintype : {type : String},
password : String,
status : String,
hash : String,
social: {},
games: Object,
os: String,
friends: Object,
msges: [{
message_id : { type: Schema.Types.ObjectId, ref: 'Message' },
read_on : Boolean }]
});
and a schema for the messages
var messageSchema = Schema({
from : String,
title: String,
msg : String,
send_on : Date
});
var Message = mongoose.model('Message', messageSchema);
This way all messages are in a collection and you can track the read status per user.
For retrieving the messages during user retriaval you can use mongoose populate
UPDATE:
if you don't want an xtra collection make your user schema something like:
var usersSchema = mongoose.Schema({
uname : {type : String , unique: true},
email : {type : String},
logintype : {type : String},
password : String,
status : String,
hash : String,
social: {},
games: Object,
os: String,
friends: Object,
msges: [{
id : Schema.Types.ObjectId,
from : String,
title: String,
msg : String,
send_on : Date,
read_on : Boolean }]
});
But keep in mind that if you also want the message to be present with the user who sended it you need to put it in the array by both users (keep id equal).... So you should think / talk about the best solution in your scenario.

Mongoose Schema with SubDocument fields that are required

Following Joe Eames tutorial, "Building AngularJS and Node.js Apps with the MEAN Stack" at Pluralsight, he demonstrates an example of a Mongoose Schema with document fields that are required, as follows:
var courseSchema = mongoose.Schema({
title: {type:String, required:'{PATH} is required!'},
featured: {type:Boolean, required:'{PATH} is required!'},
published: {type:Date, required:'{PATH} is required!'},
tags: [String]
});
I have created my own schema, with a sub-document that works:
......
skin : {styleNum : String, headerLogo: String},
......
However, I want the fields to be required and the subdocument is not an array (in Entity Framework it would be akin to an association, not a collection), so this is wrong:
......
skin : [
{styleNum : String, required:'{PATH} is required!'},
{headerLogo: String, required:'{PATH} is required!'}
]
......
What would be the correct syntax for creating an 'Entity Framework"-like association in a Mongoose Schema where both fields are required?
Nevermind, figured where my error was:
skin : {
styleNum: {type: String, required: '{PATH} is required!'},
headerLogo: {type: String, required: '{PATH} is required!'}
},

how to make a variable a unique key in mongoose?

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.

how to return full object with mongoose

i was wondering if there is a way to retrieve the full document (even with the undefined and empty keys ) .
here is my schema :
var userSchema = new Schema({
username : {type: String, index: {unique: true, dropDups: true}} ,
password : String ,
email : {type: String, index: {unique: true, dropDups: true}} ,
gender : String
})
lets say the for some user the gender isnt defined , when i query i only get the username, password and email .. how can i get the gender as well ?!
sorry if there is any wrong technical terms .
The key is to use the default attribute in a type definition to provide a default value.
var userSchema = new Schema({
username : {type: String, index: {unique: true, dropDups: true}} ,
password : String ,
email : {type: String, index: {unique: true, dropDups: true}} ,
gender : {type: String, default: "Unknown" }
})
For more information, the documentation is here.