how to return full object with mongoose - mongodb

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.

Related

What should I fill in for not so urgent field in db?

I have a db schema which requires linkedin url of the people signing up. I dont want them to fill the linkedin id on signup itself, they are free to add it at dashboard. Below given is the code for the model
const master = mongoose.model('master', new mongoose.Schema({
firstName: {type: String, required: true, unique: false},
lastName: {type: String, required: true, unique: false},
email: {type: String, required: true, unique: true },
linkedinUrl: {type: String, required: false, unique: false },
password: {type: String, required: true, unique: false}
},{strict: true}))
When I leave the field empty more than once, the db returns me an error
error: "{"driver":true,"name":"MongoError","index":0,"code":11000,"errmsg":"E11000 duplicate key error collection: maindb.mentors index: linkedinUrl_1 dup key: { : \"\" }"}"
I realise that having multiple null value is an issue. What other value can I use to mask the empty field? Thank you

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: does a custom _id need to be declared as an index and be unique

Here is the common way to define a collection structure with Mongoose :
var UserSchema = new Schema({
_id: Schema.Types.ObjectId,
username: String,
...
});
And Now I want _id field declared as Number type :
var UserSchema = new Schema({
_id: Number,
username: String,
...
});
The problem is, do I need to declare more infomation about _id ? Such as :
var UserSchema = new Schema({
_id: {type: Number, required: true, index: {unique: true}},
username: String,
...
});
I am not sure whether MongoDB would do it automatically.
if you know the answer, could you leave a comment below ? Thank you!
Well, after some practice, I realized that, MongoDB would set _id as PRIMARY KEY (NOT NULL + UNIQUE INDEX) automatically. So, just type:
_id: Number,
...

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.

Mongoose retrieval of info from multiple collections

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.