Advice for MongoDB schema design for social media post - database

I have been using MongoDB for my application but would like to add a social media post feature into the system. However, given the requirements, I find that it is not easy to come up with a MongoDB schema that would be effective for my use case. Any expert here care to share their suggestions?
The requirements are:
User can post social media post (imagine instagram posts)
User will view social media posts by other users
When a post is on a user screen for 5 second, we will record that the user has seen the post
Post that are seen will be appears in the user's social media feed
Any help would be appreciated, thank you!

You can refer below schema which we require to manage users and their post along with post history like ( who liked, who watched and who add comments)
// Users schema
const userSchema = new Schema({
name: {
type: String,
trim: true
}
});
// Post related media schema
const postMediaSchema = new Schema({
url: {
type: String,
trim: true
}
}, {
_id: false
})
// Post schema
const postSchema = new Schema({
userId: {
type: Schema.Types.ObjectId,
ref:'users',
},
title: {
type: String,
trim: true
},
description: {
type: String,
trim: true
},
media: [postMediaSchema],
tags: [String]
});
// Users and posts relation schema
const postWatchHistory = new Schema({
userId: {
type: Schema.Types.ObjectId,
ref:'users',
},
postId: {
type: Schema.Types.ObjectId,
ref:'posts',
},
});
// Post liked history schema
const postLikedHistory = new Schema({
userId: {
type: Schema.Types.ObjectId,
ref:'users',
},
postId: {
type: Schema.Types.ObjectId,
ref:'posts',
},
});
// Post comment history schema
const postCommentHistory = new Schema({
userId: {
type: Schema.Types.ObjectId,
ref:'users',
},
postId: {
type: Schema.Types.ObjectId,
ref:'posts',
},
text:{
type: String,
required: true,
trim: true
},
status:{
type: String,
enum:['Y', 'N'],
default:'N',
trim: true
}
});

Related

How can I insert mongo changes in the deploy website?

My website is running allright and it's connected with Database.
I had to add more informations in my Mongo's collection. (I created the ActionPlanSchema).
import mongoose from "mongoose";
import mongoose_delete from "mongoose-delete";
const VerificationSchema = new mongoose.Schema({
text: { type: String, required: true },
});
const ActionPlanSchema = new mongoose.Schema({
title: { type: String, required: true },
mouraTitle: { type: String, required: true },
text: { type: String, required: true },
});
const RequirementSchema = new mongoose.Schema({
itemNumber: { type: String, required: true },
normPart: {
type: mongoose.Schema.Types.ObjectId,
ref: "NormPart",
required: true,
},
generalRequirement: {
type: mongoose.Schema.Types.ObjectId,
ref: "GeneralRequirement",
required: true,
},
specificRequirementDescription: { type: String, required: true },
subject: { type: mongoose.Schema.Types.ObjectId, ref: "Subject" },
criterion: String,
verification: [VerificationSchema],
actionPlan: [ActionPlanSchema],
});
RequirementSchema.index({ itemNumber: 1, normPart: 1 });
RequirementSchema.index({ specificRequirementDescription: 1 });
RequirementSchema.plugin(mongoose_delete, {
overrideMethods: "all",
deletedAt: true,
deletedBy: true,
indexFields: ["deleted"],
});
export default RequirementSchema;
And using a router in Postman (PUT method), I added some information to the Database ActionPlanSchema. Looking like that:
In my localhost, the actionPlan information it's showing. But when I do the deploy, the actionPlan gets undefined.
I believe that it's because the informations that I added in Postman weren't sent to the database used on the Deploy App.
How can I solve this problem? (I don't know if I could be very clear about my issue)
Anyway, thanks so much!

Why is my mongoose populate query throwing "Cannot populate path because it is not in your schema" error?

I'm building a form management program but right now I'm just trying to build a queue system to handle all the forms when they're assigned to someone.
when I call this first function, it should populate the elements of the activeWork array by pulling from each collection that the entries reference, there are several collections that could be referenced in active work, so I'm trying to use the collection type field to determine what collection to pull from, I don't know if I formatted any of this correctly because its my first time building any of this.
import statesPersons from "./statesPersons.schema.js";
export async function getStatesPersonsActiveWorkByProfileId(req, res){
try{
const { profileId } = req.params
const data = await statesPersons.find({profileId})
.populate('statesPersons.activeWork.referenceId')
return res.send({
message: "success",
data: data,
status: 200 })
}catch(e) {
console.error(e.message)
return res.send({
message: "couldn't fetch active work",
data: null,
status: 500 })
}
}
Here is the schema for statesPersons, the collection where active work is stored.
import mongoose, {model, Schema} from "mongoose";
const activeWorkSchema = new Schema({
active: Boolean,
collectionType: {
type: String,
enum: ['messages'],
},
referenceId: {
type: Schema.Types.ObjectId,
refPath: "statesPersons.activeWork.collectionType"
},
sentBy: {
type: Schema.Types.String,
ref: "statesPerson",
},
sentTo: {
type: Schema.Types.String,
ref: "statesPerson",
},
timeRecived: Date,
dueDate: Date,
subject: String,
viewed: Boolean,
content: {},
})
const statesPersonsSchema = new Schema({
profileId:{
type: String,
required: true,
unique: true
},
department: {
type: String,
required: true,
index: true,
},
firstName: String,
lastName: String,
location: String,
org: String,
title: String,
jobDescription: String,
email: {
type: String,
lowercase: true,
},
phoneNumber: String,
activeWork: [activeWorkSchema],
emailList: [String],
jobAssignments: [String],
affiantInfo: {
affiantInfoTitle: String,
affiantInfoExperience: String,
},
assessments: [
{
assessdBy: {
type: Schema.Types.ObjectId,
ref: "statesPerson",
},
dueDate: Date,
questions: {},
},
],
});
export default mongoose.model("statesPersons", statesPersonsSchema);
When I make a query, I get:
Cannot populate path statesPersons.activeWork.referenceId because it is not in your schema. Set the strictPopulate option to false to override.
I don't know if I formatted my populate correctly or if the problem is in my schema,

Mapping Many To Many Relationship in Mongodb, Also considering scaling

I have a jobs collection which is like this
const JobSchema = new Schema({
jobCode: String,
companyName: String,
jobDesignation: {
type: String,
required: [true, "Please Provide Job Designation"],
},
jobVacancy: {
type: Number,
required: [true, "Please Provide Job Vacancy"],
},
postedOn: {
type: Date,
default: Date.now(),
},
})
and a users collection,
const UserSchema = new Schema(
{
firstName: {
type: String,
required: [true, "Please Provide First Name"],
},
lastName: {
type: String,
required: [true, "Please Provide Last Name"],
},
To map a many to many relationship b/w users and jobs collection where each user is able to apply to many jobs and each job can have many users, while designing the schema and considering we have to scale we cannot embed the ids in either collection because of the 16MB limit of a document, So is it better to create a third collection and have user and jobs id in it as references?
Like This
const UserJobSchema = new Schema({
job:{
type: mongoose.Schema.ObjectId,
ref: "JobSchema",
},
user:{
type: mongoose.Schema.ObjectId,
ref: "UserSchema",
},
})

Like - unlike system in MongoDb to find if user liked or not?

I'm trying to make a middleware for cheaking if user already liked the post for a React-toggle on click I've achieved a pretty good way in it in front end which i'm able to find weather user liked the post or not then toggle the button, the problem is i'm trying to match it in backend side to cheak if the likes array in schema already has the userId or not
the middleware be like
exports.liked = async (req, res, next) => {
const Liked = await Post.find( { likes : { $elemMatch: req.body.userId } } )
if (Liked){
return res.status(400).json({
error: "AlreadyLiked",
})} else {next()}
};
my mongoose schema is
let postSchema = new mongoose.Schema({
title: {
type: String,
minlength: 4,
maxength: 150,
},
body: {
type: String,
required: "Body is required",
minLength: 1,
maxLength: 2500,
},
photo: {
data: Buffer,
contentType: String,
},
postedBy: {
type: ObjectId,
ref: "User",
},
created: {
type: Date,
default: Date.now,
},likes: [{ type: ObjectId, ref: "User" }]
});
I aprreciate helps, thanks in first :)

How to save nested array of objects data using mongoose?

So, I'm sending data from angular reactive form like:
Angular reactive form UI image
and
Data being sent to backend in browser console image
I have made schema for task as:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let taskSchema = new Schema({
taskId:{
type:String,
unique:true
},
task:{
type:String,
default:''
},
subTask:[{
type: Schema.Types.ObjectId,
ref: 'SubTask'
}]
}
module.exports = mongoose.model('Task',taskSchema);
Schema for Sub-Task as:
let subTaskSchema = new Schema({
title:String,
subSubTask:[{
type: Schema.Types.ObjectId,
ref: 'SubSubTask'
}]
})
module.exports = mongoose.model('SubTask',subTaskSchema);
Schema for Sub-Sub-Task as:
let subSubTaskSchema = new Schema({
title:String
})
module.exports = mongoose.model('SubSubTask',subSubTaskSchema);
Now,I'm confused about how to save nested array of objects data in mongodb using mongoose?
you can define your schema like this
const userSchema = new mongoose.Schema({
likedBooks: [{
type: mongoose.Types.ObjectId,
ref: 'books'
}],
email: {
type: String,
required: true
},
name: {
type: String,
required: true
}
});
exports.User = mongoose.model('users', userSchema);
then you can populate data by doing
user = User.find({ email: req.body.email }).populate('likedBooks');
here likedBooks contains _id of each book
const bookSchema = new mongoose.Schema({
isbn: {
type: Number,
required: true
},
name: {
type: String,
required: true
},
author: {
type: String,
required: true
},
publisher: {
type: String,
default: ""
},
imageUrl: {
type: String,
required: true
},
description: {
type: String,
default: ""
}
});
exports.Book = mongoose.model('books', bookSchema);
for both schema i have not put _id as it is auto generated by mongodb and it is used as reference
The Object Model should look like this before saving.
{
taskId: 1,
task: 'Do something',
subTask: [{
title: 'Write a essay',
subSubTask: [{
title: 'Collect details to write an essay'
}]
}]
}
Hope it helps...

Resources