MongoDB trouble, is both way references a thing? - node.js

So I have a website built with node.js + mongoDB (mongoose). I'm having a bit trouble in the design of the database.
I want to have 2 logins, one for institutions and another for professionals. Do I need to double reference them (like the professional has a ref to Inst and an institution has a ref to the professional)?
For instance, If I want to display the list of all professionals when I login with an institution is trivial but if I don't ref the institution on the User (professional) is not so simple. So which one is better? Having code to find the user in every institution and get its institution name or both referencing each other and then do a populate?
If I pick both referencing each other, is there some way to guarantee that both of them will always be linked and having no broken only one way references?
Code:
var userSchema = new mongoose.Schema({
username: String,
password: String,
email: String,
name: String,
created_at: {type: Date, default: Date.now},
status : Boolean,
institution: { type:mongoose.Schema.ObjectId, ref:'Inst' }
});
mongoose.model('User', userSchema);
var User = mongoose.model('User');
var instSchema = new mongoose.Schema(
{
name : String,
professional : [{ type:mongoose.Schema.ObjectId, ref:'User'}]
});
mongoose.model('Inst', instSchema);
var Inst = mongoose.model('Inst');

How about just merge instSchema into userSchema as below, with additional user_type to indicate which type this user belong to, Professional or Institutions. Also one new related_user to store the other related User documents
var userSchema = new mongoose.Schema({
username: String,
password: String,
email: String,
name: String,
created_at: {type: Date, default: Date.now},
status : Boolean,
user_type: {type: String, enum: ['Prof', 'Inst']},
related_user: [{ type:mongoose.Schema.ObjectId, ref:'User'}]
});
mongoose.model('User', userSchema);
var User = mongoose.model('User');

Related

Creating different types of users in mongodb

I want to create an API to register, login and other things. two types of users
A teacher and a student , I'm using MongoDb and defining the schema.
const UserSchema = new Schema({
studentInfo : {
name: String,
email: String,
password: String,
birthday: Date,
state: String,
zip_code: String,
address: String,
phone_number: String,
},
teacherInfo : {
name: String,
email: String,
password: String,
birthday: Date,
state: String,
zip_code: String,
address: String,
phone_number: String,
course: {
title: String,
price: Number,
description: String
}
},
role: String
});
is this a good approach? or there is a better way?
I added the role field to perform route guarding on the front end.
I'm using Nodejs and Express.
any help will be much appreciated, thank you.
This is one way of embedding both student and teacher object in the same document and you can simply get data with single query. Although you don't need to separately embed the common fields in object like name, email, password, phone_number etc. teacherInfo would be like this
teacherInfo : {
course: {
title: String,
price: Number,
description: String
}
}
You can create different schemas for student and teacher (as they are unique and you might need them independent sometimes), and make User as the base model.
var User= new Schema({
name: String,
email: String,
password:String,
birthday: Date,
state: String,
zip_code: String,
address: String,
phone_number: String,
_teacher:{type:Schema.Types.ObjectId, ref:'Teacher'},
_student: {type:Schema.Types.ObjectId, ref:'Student'}
});
If _teacher has a value then the user can be considered as a teacher.
If _student has a value then the user can be considered as a student.
//Teacher Model
var Teacher = new Schema({
course: {
title: String,
price: Number,
description: String
},
//other teacher's fields
})
//Student Schema
var Student= new Schema({
//student's fields if you need in future
})

Unable to check whether the value exists inside nested Model in mongoose

I am creating poll app. My schema definitions are as below
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/pollApp');
var userSchema = new mongoose.Schema({
username: { type: String, required: true},
phonenumber: { type: String, required: true, unique: true}
});
var option = new mongoose.Schema({
title: {type: String, required: true},
votes: { type: Number, default: 0 },
voterList: {type: []}
});
var poll = new mongoose.Schema({
question: { type: String, required: true, unique: true},
options: { type: [option], required: true},
showVoters: {type: Boolean, default: false}
});
mongoose.user = mongoose.model('User', userSchema);
mongoose.poll = mongoose.model('Poll', poll);
module.exports = mongoose;
voterList will contain all the voters name.Before adding vote i want to check whether user has already voted for the poll(need to check user exists in each voterList array). How to accomplish this?
If you want unique values in the voterList array, you can use $addToSet for pushing a user in the voterList.
but if you want to do some kind of validation. It is better you do a get query which checks if user is already present in the array.
if yes, throw a message saying user already voted else add the user to voterlist
For checking an user is already present in voterList array, it is very simple actually.
You can use a find query like below:
find({voterList:'585ce839c84f5d3d1ef15d56'})
Even if voterList is an array, mongo will see if the provided value is present in the array or not.

Mongoose Ref User Object

I hope everyone learning something today. I need some help. I have a Gift model which looks something like this:
let giftSchema = new mongoose.Schema({
gift: String,
date: {
type: Date
},
giftDescription: String,
giftAmount: String,
giftCode: String,
redeemCode: String,
passCode: String,
senderFirstName: String,
senderLastName: String,
giftMessage: String,
user: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
username: String
}
});
module.exports = mongoose.model('Gift', giftSchema);
This is my user model:
const mongoose = require('mongoose'),
passportLocalMongoose = require('passport-local-mongoose');
let UserSchema = new mongoose.Schema({
firstName: String,
lastName: String,
alaisFirstName: String,
alaisLastName: String,
username: String,
password: String,
isAdmin: Boolean,
addressLine1: String,
addressLine2: String,
city: String,
state: String,
zipCode: String
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model('User', UserSchema);
I have pretty much 2 users, and no guest. The admin sends gifts to a user. So as an admin, on the new route, I need to send something to the user. However, in my field: for ( think gmail search field ) I will be searching for either firstName, lastName, alaisFirstName, and alaisLastName than sending the gift to the user.
How could I model that? I cant do it by type: mongoose.Schema.Types.ObjectId, because the admin is the one sending it to the user, but I want something similar to that.

Complex sort with Mongoose

I'm new in Mongoose and I want to create a 'complex' sorting. So I have the following schemas:
var UserSchema = new Schema({
firstName: String,
lastName: String,
...
skills : [{ type: Schema.Types.ObjectId, ref: 'Skill' }]
});
var ProjectSchema = new Schema({
name: String,
description: String,
...
skills : [{ type: Schema.Types.ObjectId, ref: 'Skill' }]
});
var SkillSchema = new Schema({
name: String
});
So given those schemas what I need is to sort by the matching percentage between the user skills and the project skills, so basically I want to show first the projects that are more related to the user. Is that possible by using just mongoose? If so I guess I will need to create a sorting function that I can pass to the query or something.
Thank you!

Error while defining mongoose schemas

I am new to mongo and mongoose. I am trying to create 3 collections Users, Articles and Comments. I want the users documents should contain articles that users have saved. The articles object should have users and comments as embedded objects and comments should have embedded user objects.
I want this to be done using the ids of the individual objects so that I can reduce the loading time, but could not find a suitable way to do so using mongoose. Please suggest how should I proceed with the Schema implementation.
var UserSchema = new mongoose.Schema({
name: String,
email: String,
profilePicture: String,
password: String,
readingList: [articleSchema]
});
var commentsSchema = new mongoose.Schema({
content: String,
votes:{
up:[UserSchema],
down:[UserSchema]
},
comments:[commentsSchema],
timestamp:Date.now
});
var articleSchema = new mongoose.Schema({
title: String,
content: String,
image: String,
votes:{
up: [UserSchema],
down: [UserSchema]
},
comments:[commentsSchema],
timestamp: Date.now
});
What you have is failing because articleSchema isn't defined when you're using it in the UserSchema. Unfortunately, you can reverse the order of defining the schema because they're dependent on each other.
I haven't actually tried this, but based on some quick googling there is a way to create the Schema first and then add the properties.
var UserSchema = new mongoose.Schema();
var CommentsSchema = new mongoose.Schema();
var ArticleSchema = new mongoose.Schema();
UserSchema.add({
name: String,
email: String,
profilePicture: String,
password: String,
readingList: [ArticleSchema]
});
CommentsSchema.add({
content: String,
votes:{
up:[UserSchema],
down:[UserSchema]
},
comments:[CommentsSchema],
timestamp:Date.now
});
ArticleSchema.add({
title: String,
content: String,
image: String,
votes:{
up: [UserSchema],
down: [UserSchema]
},
comments:[CommentsSchema],
timestamp: Date.now
});

Resources