Sails.js with mongodb design - javascript

just starting out in sails.
Currently I have a User Model set up. I also have another Founder Model to store information specific to Users who are also Models.
attributes: {
companyName: {
type: 'string',
required: true
},
tagLine: {
type: 'string',
required: true
},
location: {
type: 'string',
required: true
},
market: {
type: 'string',
required: true
},
psName: {
type: 'string',
required: true
},
psDesc: {
type: 'string'.
required: true
}
}
So my question in the FounderController...would inputting the unique id for the user from User for the database be implemented in the models or in the controller? The Founder model will essentially create it's own unique id.
My first approach would to basically find the ID from the User documents, store it into a variable, update the Founder document's id field with the user id?
I felt this isn't very efficient. Thanks.

Related

ObjectIDs in other collections without getting duplicate key error

I am getting the following error when trying to create a document in a collection.
MongoServerError: E11000 duplicate key error collection: stock-trading-system-db.trades index: user_id_1 dup key: { user_id: ObjectId('6266de71b90b594dab9037f3') }
Here is my schema:
const tradeSchema = new mongoose.Schema({
user_id: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
stock_id: {
type: Schema.Types.ObjectId,
ref: 'Stock',
required: true
},
stock_amount: {
type: Number,
required: true
},
stock_value: {
type: Number,
required: true
},
time_of_trade: {
type: Date,
required: true,
default: new Date()
},
trade_status: {
type: String,
enum: ['Approved', 'Declined', 'Pending'],
required: true,
default: 'Pending'
}
}, { collection: 'trades' })
I don't want user_id and stock_id to be unique, i just want it to check that those ObjectIDs exist in their respective collections before making the trade document. How do i achieve this?
It looks like a collection saves the schema that is defined in mongoose, and even if you change the schema, the unique values will stay the same inside the collection.
So even though i had removed
unique: true;
from my mongoose schema, it hadn't removed this from the collection in my DB.
Therefore the solution to this is to delete the collection and recreate it.

how can i efficiently model my Mongoose Schema's?

Good Morning all! - i'll try to keep it short.
Coming from a begginers SQL/EF background i definitely went into mongoose with the wrong mindset.
I have 3 tables:
Users /
Boards /
BoardObjects
Now originally i thought about storing the boards as an array in the users document. But i think i'm approaching this wrong and i need community advice.
i need to be able to query what users what own what boards, and what objects are on those boards, and the arrays i put in were a nightmare. Then i thought, do i even need to cross these over?
for example, if i store a User, and then create a board, and in the board has a UserId that has to be unique to the user, and same for the BoardObjects, UserId and a BoardId, from what i've read so far seems it might be possible this way using joins and whatnot, which ive still got to learn..
Whats the community view here? do you embed or normalise often? or is this a valid way of managing related data in mongoose?
Providing Boards model for context
const Board = mongoose.model('Board', new mongoose.Schema({
Ownerid: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'User'
},
name: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
datecreated: {
type: Date,
},
datemodified: {
type: Date
},
BoardObjects: [{ boardobjectid: { type: mongoose.Types.ObjectId, ref: 'BoardObject' } }],
}));
if i am understanding you correctly, you need to create a relationship between the two tables. in the user model you can add something like.
userSchema.virtual('boards', {
ref: 'Boards',
localField: '_id',
foreignField: 'owner'
});
then as part of your boards model build your relationship with the user as an object on the model like this.
owner:{
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'User'
}
I hope this helps!
As per my knowledge,You can go with following answer as below:
const Board= new mongoose.Schema({
Ownerid: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'User'
},
name: {
type: String,
required: true,
minlength: 5,
maxlength: 50
},
datecreated: {
type: Date,
},
datemodified: {
type: Date
}
})
const Board=mongoose.model('Board',userSchema)

How to verify if email exists in two seperate documents of mongoose?

I have two models, patients and doctors. When the user signs in, be it the doctor or patient, there is only one route which runs the login function of the backend. But what I fail to understand is how to query such that it searches in both collections of patients and doctors by using single query.
This is the doctor model:
const doctorSchema = new Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
practitionerLicense: {
type: String,
required: true
}
});
module.exports = Doctor = mongoose.model("doctors", doctorSchema);
And the patient model:
const patientSchema = new Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
module.exports = Patient = mongoose.model("patient", patientSchema);
Now I want something like the following pseudo code where users could be like a base class or something.
Users.findOne({email}).then(...)
I went through many other similar questions but saw methods like populate which I believe would not suit my case. Any suggestions?
Your patient and doctor schemas are almost same except the practitionerLicense field.
So instead of two different schemas, I would create a common user schema with an additional role field like this:
const userSchema = new Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
practitionerLicense: {
type: String,
required: false
},
role: {
type: String,
enum: ["patient", "doctor"],
required: true
}
});
module.exports = User = mongoose.model("users", userSchema);
Note that I also set practitionerLicense's required option to false.
This way you can use a common user login form and route.
Your register route and register form in React can also be common, if you could verify if a user enters a practitioner license, and you can validate it using an API if there is such an API.
If that is not possible, your register routes and register components must be different for patient and doctor. When a user registers in patient register form, you can set role to patient. And when a user registers in doctor register form, you can set role to doctor.

Duplicate key error collection with unique field

I am getting a MongoDB error when trying to insert a document without nickname second time. The document already have unique field and non required.
Here is my Mongoose model:
var schema = new Schema ({
username: {
type: String,
required: false
},
nickname: {
type: String,
required: false,
unique: true,
trim: true
},
status: {
type: String,
required: false,
trim: true,
minlength: 1,
maxlength: 100
},
avatar: String,
online: {
type: Boolean,
default: false
},
created: {
type: Date,
default: Date.now
},
device: {
type: ObjectId,
ref: 'Device',
required: false
},
createdRooms:[{
type: Schema.Types.ObjectId,
ref: 'Room'
}],
facebook: {
facebookToken: {
type: String,
required: false,
trim: true,
unique: false
},
facebookId: {
type: String,
required: false,
trim: true,
unique: false
}
}
},
{
toObject: {
virtuals: true
},
toJSON: {
virtuals: true
}
});
For the first time, the document without a nickname is added to the database, but when I want to save another document without a nickname, I get an error:
MongoError: E11000 duplicate key error collection: grooptag.users index: nickname_1 dup key: { : null }
So I looked up "MongoDB not required but unique" and I found this: mongoDB/mongoose: unique if not null
It seems you need to use sparse: true instead of required: false to get what you want.
Edit: Reading up the MongoDB documentation on sparse indexes, however, I was redirected to partial indexes which seem to be the way to go from MongoDB 3.2 onward: https://docs.mongodb.com/manual/core/index-partial/#index-type-partial
The problem is that while the documentation clearly states:
Partial indexes represent a superset of the functionality offered by sparse indexes and should be preferred over sparse indexes.
It does not seem to be true for sparse and unique indexes, since they also state on the same page:
A partial index with a unique constraint does not prevent the insertion of documents that do not meet the unique constraint if the documents do not meet the filter criteria.
Way to contradict themselves... :/

Sails.Js - Simple Exercise with 2 Relations on the ORM

I'm new to Sails.js and Node.js, so if i'm asking a simple question please forgive me.
I'm doing an API that must have a database, and i wanted to implement MySQL because i have some relations between tables. So i wrote the relational model by hand, like it is on the figure:
And i tried to implement is using sails.js, but for some reason i can't get the relation Level to Score working while the User-Score relationship is working fine.
Here are my models:
User.JS
module.exports = {
attributes: {
name:{
type:'string',
required: true
},
address:{
type: 'string'
},
email:{
type: 'string',
email:true,
unique: true,
required: true
},
encryptedPassword:{
type: 'string'
},
tranusertoscore:{
collection:'scores',
via: 'transcoretouser'
}
}
}
Level.js
module.exports = {
attributes: {
lvl_name:{
type: 'string',
required: true
},
tranleveltoscore:{
collection: 'scores',
via: 'transcoretolevels'
}
}
};
and finally
Score.js
module.exports = {
attributes: {
lvl:{
type: 'string',
required: true
},
score:{
type: 'integer',
required: true
},
transcoretouser:{
model: 'user'
},
transcoretolevels:{
model: 'level'
}
}
};
So, can you guys tell me what i'm doing wrong?
Sorry to take your time if the answer is easy, but i tried to follow documentation and search about the subject and didn't find any relevant answers.

Categories

Resources