Reputation: 123
I am just learning how to build websites using MEANJS, and I am structuring my data but unsure on the best practice, I am very new to the NoSql concept.
I need to store:
questions
answers
likes
saved_questions
In my app I enable the user to save questions to be viewed later, as well as they can access any answer they posted. And I provide some stats for each question (i.e. number of likes, number of answers, etc)
Should I create one document for "question" and everything inside of it:
{_id: <ObjectId>,
user_id: <ObjectId>,
question: 'how can we....',
answers: [{user_id: <ObjectId>, answer: ''}],
likes: [{user_id: <ObjectId>}],
saves: [{user_id: <ObjectId>}]
}
Or should I make multiple documents for each? Or should I use both methods?
Upvotes: 4
Views: 4286
Reputation: 78
I would have at least two database models, maybe one for the User and the other for the Question. One of the great things about the MEAN.JS boiler plate is that it already comes with a User module complete with sign-up, login/logout functionality. So you have that out of the way as soon as you deploy your new project.
With that already out of the way, I would use the Yo Generator to create a new CRUD module called Question. You can add the files manually, but Yo helps you do it quickly and accurately by automatically placing the files in the correct place, complete with sample code to help you set it up. To learn how to use the Yo Generator I would look at the Yo Generator Section of the MEAN.JS docs.
From your app's root directory, run yo meanjs:crud-module Question
. This will create all of the necessary files you need for the database model, as well as a new module on the front & back ends with samples of how to create/read/update/delete the questions. Now, if you log in, you will see the new module in your menu bar.
Then open app/controllers/models/question.server.model.js
. This is the file that you can define your new database model. Depending on how complex/relational you want the data to be, you'd want your Mongoose model to look something like this:
var QuestionSchema = new Schema({
created: {
type: Date,
default: Date.now
},
title: {
type: String,
default: '',
trim: true,
required: 'Title cannot be blank'
},
question: {
type: String,
default: '',
trim: true
},
user: {
type: Schema.ObjectId,
ref: 'User'
},
answers: {
type: Array,
default: []
},
likes: {
type: Array,
default: []
},
saves: {
type: Array,
default: []
}
});
Obviously this is very simplified. You may want to create separate mongoose models for the likes, saves, and reports so you can store more data about each (ie: user_id, date, reason for reporting/saving/liking, etc.) To read more about how to make the perfect mongoose model for your needs, I would definitely check out the docs about Mongoose Schemas at mongoosejs.com.
I hope that helps!
To get a list of a given user's actions, I would go ahead and make a new Mongoose Schema for each type of action (comments, likes, saves), and store the details of user's actions there. For instance, in Answers schema you could store the actual comment, who said it, when they said it, what question it was for etc. Then simply query the action tables for a given user ID to retrieve your list of actions.
So..
var QuestionSchema = new Schema({
created: {
type: Date,
default: Date.now
},
title: {
type: String,
default: '',
trim: true,
required: 'Title cannot be blank'
},
question: {
type: String,
default: '',
trim: true
},
user: {
type: Schema.ObjectId,
ref: 'User'
}
});
var AnswerSchema = new Schema({
created: {
type: Date,
default: Date.now
},
question: {
type: Schema.ObjectId,
ref: 'Question'
},
user: {
type: Schema.ObjectId,
ref: 'User'
},
answer: {
type: String,
default: '',
trim: true
}
});
Upvotes: 6