I Have schema design as below. I have posts array which is reference to the post model. Is it good idea to put it in User schema or should I not include as it is always growing as users add their post. I guess I should only put accesstokens in reference and not posts. Am I thinking right?
var UserSchema = new Schema({
username: {
type: String,
unique: true,
required: true,
lowercase: true,
trim: true
},
encrypted_password: {
type: String,
required: true
},
salt: {
type: String,
required: true
},
email: {
type: String,
unique: true,
required: true,
lowercase: true,
trim: true
},
mobile: {
type: Number,
unique: true
},
bio: {
type: String
},
created: {
type: Date,
default: Date.now
},
access_tokens: [{type: Schema.Types.ObjectId, ref: 'AccessToken'}],
posts: [{type: Schema.Types.ObjectId, ref: 'Post'}]
}, { collection: 'users' });
You should have a separate collection for Posts but you should keep the access_tokens within the user schema. One good reason you might consider separating the posts into its own collection is there are many use cases where you will query for just posts. However, with access_tokens, they will always be tied to a user.
tldr;
Posts should have their own schema
Access tokens should be in user schema
Hope that helps!
Related
Right now i'm thinking of doing it like this:
Board:
const BoardSchema = new Schema({
title: {
type: String,
required: true,
},
admins: [
{
type: ObjectId,
ref: 'User',
required: true,
}
],
members: [
{
type: ObjectId,
ref: 'User',
required: true,
}
],
}, {
timestamps: true,
});
List:
const listSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
order: {
type: Number,
required: true,
},
boardId: {
type: ObjectId,
required: true,
ref: 'Board',
},
});
Card:
const cardSchema = new Schema({
text: {
type: String,
required: true,
},
members: {
type: ObjectId,
ref: 'User',
required: true,
},
listId: {
type: ObjectId,
ref: 'User',
required: true,
},
boardId: {
type: ObjectId,
ref: 'Board',
required: true,
},
order: {
type: Number,
required: true,
},
});
I'm new to mongoDB/noSQL and a database noob in general, and structuring a database seems to not be a very strict science, as everyone seems to do it differently. From what i've seen the rule of thumb is to keep as much data in one collection as possible, basically the opposite of traditional databases, but not always? So should i instead save everything in the Board collection?
Going forward with this project i want to try to replicate how one would do in a real scenario to learn as much as possible. And i've been googling around to try and find the schema structure for the real trello app but i cannot find it. All i know is that they do use mongoDB and they have a separate Collection for Cards because with the amount of data they handle it wouldn't work otherwise. So i assume they have a separate Collection for Lists (and Boards) aswell.
So my question is if these Schemas would work? And what would be the best way to go about getting all the data (when a user clicks on a board) using the boardId and combining it into a List of Cards?
I have a problem with a mongoose population and I don't know what I should do.
I got two schemas:
var userSchema = new userSchema({
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
mods: [{ type: mongoose.Schema.Types.ObjectId, ref: 'users'}]
});
var dataSchema = mongoose.Schema({
title: { type: String, required: true, unique: true },
description: { type: String, required: true },
owner: {type: mongoose.Schema.Types.ObjectId, required: true}
});
So one user can have several data packages.
Some users are moderated by other users.
Whats the query for a moderator, that all his own data packages and the ones of the users he is moderating are listed?
You see that I have a SQL background and there's definitely another way to do it with MongoDB.
Thanks for your help!
I'm not clear understand what queries do you need but first you need set ref property in 'owner' field in dataSchema. As about population it's look like this:
//if you use callback
users.find({/*your query*/}).populate('mods')
.exec((err, result)=>{/*your code*/});
//if you use promise
users.find({/*your query*/}).populate('mods').exec()
.then(result=>{/*your code*/})
.catch(err=>{throw err});
I'm building a MEAN stack video app (I'm pretty new to Node and Mongodb) and I need a way to keep track of videos watched. How do I do this?
I was thinking I could have an array of Ids in the user collection that references videos but I'd like to be able to return videos with a watched: true key value pair that's dependent on the user making the request. If this is a good way to do it, how do I return a key value pair that's dependent on another document in another collection?
User model:
let UserSchema = new mongoose.Schema({
email: {
type: String,
required: true,
minlength: 1,
trim: true,
unique: true,
validate: {
validator: VALUE => validator.isEmail(VALUE),
message: '{VALUE} is not a valid email'
}
},
password: {
type: String,
required: true,
minlength: 6
},
admin: {
type: Boolean,
default: false
},
vid_inprogress: {
type: mongoose.Schema.Types.ObjectId
},
vid_completed: [{ type : mongoose.Schema.Types.ObjectId, ref: 'Attachment' }],
tokens: [{
access: {
type: String,
required: true
},
token: {
type: String,
required: true
}
}]
});
Video Model:
var Video = mongoose.model('Video', {
url: {
type: String,
required: true,
minlength: 1,
trim: true
},
title: {
type: String,
required: true,
default: '',
trim: true
},
description: {
type: String,
default: '',
trim: true
},
img: {
type: String,
default: '',
trim: true
},
attachments: [{ type : mongoose.Schema.Types.ObjectId, ref: 'Attachment' }]
});
vid_completed on the User model is where I'd like to keep track of the video ids that have been watched. And the Video model is what would be returned with a key: value pair based on whether the video id is found in the user vid_completed array. Let me know if that makes sense. Thanks in advance!
I ended up just using an array in the User model like so:
vid_inprogress: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Video'
},
vid_completed: [{ type : mongoose.Schema.Types.ObjectId, ref: 'Video' }]
I'll just have to add watched: true on the front end. Let me know if you have a better way. I'd be interested to hear.
I am developing an app like Tinder to experiment with MongoDB.
I am wondering about the database schema.
The main idea is that a user can "like" many users but no matter how much the number of "liked" profiles grows, it is very unlikely to hit the 16MB document size ceiling, so in my design, "liked" profiles are embedded inside one's profile.
below is a sample of my users schema using mongoose
var UserSchema = mongoose.Schema({
fullName: {
type: String,
trim: true
},
phone: {
type: String,
trim: true,
required: true,
},
gender: {
type: String,
enum: ['male', 'female'],
},
age: {
type: Number,
required: true
},
favorites: []
});
On the other hand, a user might be "disliked" by my many users.
So a user should not see on his next profile search the profiles of users who "disliked" him, so in my design I created a collection that holds the ID of the user who "disliked" and the ID of the user being "disliked".
below is a sample of my blocked schema using mongoose
var BlockedSchema = mongoose.Schema({
BlockerUserId: {
type: String,
required: true
},
BlockedUserId: {
type: String,
required: true
}
});
Do you think this is a good approach? and which indexes needs to be created?
Best,
You can manage dislike in the user collection only, you don't need a new collection.
var UserSchema = mongoose.Schema({
fullName: {
type: String,
trim: true
},
phone: {
type: String,
trim: true,
required: true,
},
gender: {
type: String,
enum: ['male', 'female'],
},
age: {
type: Number,
required: true
},
favorites: [],
dislike[]
});
and search like
var current_user_id = userdata._id;
db.users.find({dislike:{$ne:current_user_id}})
The above code is not syntactically correct but it will give you an idea.
I have this mongoose schema, I added updated_by and created_by, but for some reason when I save models from client to server, those fields aren't visible:
userSchema = mongoose.Schema({
role: {
type: String,
enum: ['Admin', 'Owner', 'User']
},
username: {
type: String,
unique: true,
required: true,
validate: [validation.usernameValidator, 'not a valid username']
},
passwordHash: {
type: String,
required: true,
validate: [validation.passwordValidator, 'not a valid password']
},
email: {
type: String,
unique: true,
required: true,
validate: [validation.emailValidator, 'not a valid email address']
},
firstName: {
type: String,
required: false
},
lastName: {
type: String,
required: false
},
registered_at: {
type: Date,
default: Date.now
},
created_by: {
type: String,
required: false
},
updated_by: {
type: String,
required: false
},
created_at: {
type: Date,
default: Date.now
},
updated_at: {
type: Date,
default: Date.now
}
},
{
autoIndex: false
});
is this normally a problem? Do I have to somehow rebuild something with Mongoose or MongoDB in order for them to pick up the new properties on this model?
Of course, I did restart the mongoDB server, but that didn't do anything.
In any case, if you save your User model, the fields with actual values shown in MongoDB will be the ones you set a value for yourself when saving the model OR the fields with a default value set in your userSchema.
So, just to clarify on this:
address: { type: String, default: ' ' }
will be shown in MongoDB with a value of ' ' unless you set a specific address when saving your User model.
But,
address: String
will NOT be shown in MongoDB unless you set a specific address when saving your User model.
EDIT
Thanks to Matthew for pointing it out, actually upsert behavior is indeed the following:
If upsert is true and no document matches the query criteria, update() inserts a single document.