How to keep track of videos watched with Node.js and Mongodb - node.js

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.

Related

Mongoose: Path is required at .findById()

I'm making a Blog with Node.js and a MongoDB (Mongoose) database in which users can share their blog.
I HAD a SubmittedBlog model like this:
const SubmittedBlogSchema = new mongoose.Schema({
blogType: {
type: String,
required: true
},
text: {
type: String,
required: [true, 'Please enter a text'],
minlength: [50, 'Text must be at least 50 characters long'],
maxlength: [2000, 'Text must be at most 2000 characters long'],
trim: true
},
...
});
But then I had to add another field object called submitter which contains information about the blog submitter:
const SubmittedBlogSchema = new mongoose.Schema({
blogType: {
type: String,
required: true
},
submitter: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true
},
username: {
type: String,
required: true
}
},
...
});
Note that this object is required. However If I want to SubmittedBlog.findById() now, it isn't working and it errors out that "Path submitter.username is required". I thought that this would only happen at saving a submitted blog but why is this at finding a blog???

Trouble with mongoDB Ref -> trying to ref array of diferent model

so i'm trying ref a array of daysOff (Ferias model) as a fiel in a User model,
i'm new to MongoDB and mongoose, and i'm trying to build a API that manages a company workers days off.
I apologyse in advance for the "format" of this question but it's the very first time that I post a question in StackOverflow :)
Thanks u all!
const mongoose = require("mongoose");
const moment = require("moment");
const feriasSchema = mongoose.Schema(
{
user: {
type: mongoose.Types.ObjectId,
required: true,
ref: "User",
},
firstName: {
type: String,
ref: "User",
},
lastName: {
type: String,
ref: "User",
},
workerNumber: {
type: Number,
ref: "User",
},
sectionOfWork: {
type: String,
ref: "User",
},
totalFerias: {
type: Number,
required: true,
},
//this is the field i want to add in User model as an array of (dates format DD/MM/YYYY)
ferias: {
type: [String],
//default: [Date],
required: true,
},
tipoFerias: {
type: String,
required: true,
},
modo: {
type: String,
required: true,
},
},
{ timestamps: true }
);
module.exports = mongoose.model("Ferias", feriasSchema);
// USER MODEL
const userSchema = mongoose.Schema(
{
firstName: {
type: String,
required: true,
},
lastName: {
type: String,
required: true,
},
email: {
type: String,
required: [true, "Please enter a valid email address"],
unique: true,
},
password: {
type: String,
required: [true, "Please enter a password"],
},
workerNumber: {
type: Number,
required: true,
unique: true,
},
sectionOfWork: {
type: String,
required: true,
},
chefia: {
type: String,
required: true,
},
//this is the field i want to be an array (from Ferias model)
ferias: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Ferias",
}],
role: {
type: String,
required: true,
},
},
{ timestamps: true }
);
module.exports = mongoose.model("User", userSchema);
what am i doing wrong?
i'm getting and empty array ...
in express I can send the questioned data separately but u want to send a json to some frontend with all the fields of a user, with the "ferias" array present.

How to populate object having array of object in mongoose?

I want to populate the adminId path to User Model.
Here is the code
adminInfo: {
_id: false,
adminId: [{
type: Schema.Types.ObjectId,
ref: 'User'
}]
}
Here is a part of user schema:
// user schema
const UserSchema = new mongoose.Schema({
name: {
firstName: {
type: String,
trim: true,
required: true,
},
lastName: {
type: String,
trim: true
}
},
email: {
type: String,
trim: true,
required: true,
unique: true,
lowercase: true
},
phone: {
type: String,
trim: true,
minlength: 10,
},
password: {
type: String,
trim: true,
required: true,
minlength: 6
}
});
I have tried using .populate('adminInfo.adminId') but it's giving empty array [] whereas .populate('adminInfo') giving array of admins ids but not getting populated to User model
i don't think there is any problem with .populate('adminInfo.adminId') method.
are you sure that ref field is in CamelCase .
If not, try to change ref field ->
adminInfo: {
_id: false,
adminId: [{
type: Schema.Types.ObjectId,
ref: 'user'
}]
}

Best way to structure mongoDB schemas for a Trello-like app using mongoose?

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?

Pass a hardcoded value through mongoose schema

I would like to post some hard coded values along with user input(variables) every time.
args: [{ type: mongoose.Schema.Types.Mixed, required: true }] >>in this array i would like to pass some hard coded values along with user input variables.
Well my data to be posted looks like this.
{"file": "**<user input>**","name":"<user input>", "className": "com.izac.Parser.IO", "args": ["-i", "{\"enrichedKafkaOptions\": {\"checkpointLocation\": \"**<hard coded path always remains the same>**", \"kafka.bootstrap.servers\": \"localhost:9092\", \"topic\": \"demoEnriched\"}, \"rejectedKafkaOptions\": {\"checkpointLocation\": \"/Users/vipulrajan/Desktop/checkpoints/DemoRejected\", \"kafka.bootstrap.servers\": \"localhost:9092\", \"topic\": \"demoRejected\"} }","-s", "{\"master\":\"local[*]\", \"appName\":\"app1\", \"config\":{\"jvm.memory\":\"4g\"} }"]};
This is my schema,
const mongoose = require('mongoose');
const livy_schema = mongoose.Schema({
file: { type: String, required: true },
name: { type: String, required: true },
className: { type: String, required: true },
args: [{ type: mongoose.Schema.Types.Mixed, required: true }] //here i have constants to pass on to
});
const kafka_schema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: { type: String, required: true, unique: false },
config: { type: mongoose.Schema.Types.Mixed, required: true } //here i have constants to pass on to
});
const enrichedEventSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
projectId: { type: mongoose.Schema.Types.ObjectId, ref: 'Project', required: true },
name: { type: String, required: true, unique: true },
description: { type: String, required: false },
type: { type: String, enum: ["Enriched"], required: true },
format: { type: String, enum: ["JSON", "DELIMITED", "FixedWidth", "LOG"], required: true },
kafka: [kafka_schema],
livy: [livy_schema]
});
Original question Asynchronous Programming in node js to pass constants/predefined mandatory values through mongoose model .
I'm kind of in dilemma, like should i pass this hardcodeded values in router.post() method(if its possible, how should i code?) or in schema? please guide me in right direction.
Please excuse me if I am misunderstanding the question.
Since you are using mongoose schema you can have your field default be a function where you can initialize and add hardcoded values.
Something like this:
const livy_schema = mongoose.Schema({
file: {
type: String,
required: true
},
name: {
type: String,
required: true
},
className: {
type: String,
required: true
},
args: [{
type: mongoose.Schema.Types.Mixed,
required: true,
default: function() {
return { data: 'hardcoded!', info: 'hardcoded!' }
}
}] //here i have constants to pass on to
});
)
if the schema is in the right context I assume you can easily replace those strings with values being passed or swap the default function.

Resources