mongoose comments and replies schema - mongodb

I am following this link to understand how to design my schema for a social media type module with comments and replies. https://www.xuchao.org/docs/mongodb/use-cases/storing-comments.html#gsc.tab=0 (This is for mongdb and not mongoose)
I am trying to create a schema like this
const socialSchema = new mongoose.Schema({
Entry_Number: Number,
Player_Name: String,
Player_Message : String,
Player_Fullmessage: String,
Player_ProfilePic : String,
Player_UploadedPic: String,
Player_UploadedVideos: String,
Status_Date: String,
Status_Feeling: String,
Google_Profile: String,
Status_Likes: [{Like_Number: Number, Liked_By: String}],
Status_Comments: [
{Comment_Number: Number,
Comment_By: String,
Comment_Message: String},
replies: [
{Comment_By: String,
Comment_Message: String}
],
],
Friends: { type: Array, default: []},
Shares: { type: Array, default: []},
Shared_Post: String,
Shared_Newmessage: String,
Shared_PostDetails: [{type: Schema.Types.ObjectId, ref: "socialdatas"}]
The problem I am facing is with the replies. My logic tells me that the replies should be a array within the main comments array. However the cods as it is above, gives me an error while compiling. SyntaxError: Unexpected token ':'
Am I approaching this correctly? Any experts that can give me some advice. Thanks.

I would suggest create a separate schemas for comments and players, then you can just use populate() to access data between collections.
but to fix your issue above, it should be like this:
Status_Comments: [{
Comment_Number: Number,
Comment_By: String,
Comment_Message: String,
replies: [
{Comment_By: String,
Comment_Message: String}
]
}]

Related

Mongoose nested array update

Hey folks this is how my schema looks.
const socialSchema = new mongoose.Schema({
Entry_Number: Number,
Player_Name: String,
Player_Message : String,
Player_Fullmessage: String,
Player_ProfilePic : String,
Player_UploadedPic: String,
Player_UploadedVideos: String,
Status_Date: String,
Status_Feeling: String,
Google_Profile: String,
Status_Likes: [{Like_Number: Number, Liked_By: String}],
Status_Comments: [{
Comment_Number: Number,
Comment_By: String,
Comment_Message: String,
replies: [
{Comment_By: String,
Comment_Message: String}
]
}],
Friends: { type: Array, default: []},
Shares: { type: Array, default: []},
Shared_Post: String,
Shared_Newmessage: String,
Shared_PostDetails: [{type: Schema.Types.ObjectId, ref: "socialdatas"}]
});
I am trying to update the replies nested array inside the Status_Comments array, from values coming from the front end.Here is where I am after multiple tries.
socialRegister.findOneAndUpdate({_id: req.body.hiddentextcommentid3, "Status_Comments._id": req.body.hiddentextcommentid3a},
{$push: {"Status_Comments.$.replies":
{
"Comment_By": req.user.Player_Name,
"Comment_Message" : req.body.replymessage
}}}, function(err,data1)
I dont get any error on my terminal, but there is no update happening also. Can someone please help?
try this one:
let reply = {
"Comment_By": req.user.Player_Name,
"Comment_Message" : req.body.replymessage
}
socialRegister.findOneAndUpdate({"Status_Comments._id":req.body.hiddentextcommentid3a},
{$push: {"Status_Comments.$.replies": reply }},{new: true},
(err,data) =>{
console.log(data)
})

Looking for MongoDB schema suggestions

I'm relatively new to MongoDB and I'm wondering what the "best" solution would be for handling the following type of data in my database.
Collections:
Users
Lessons
Overview:
Note: Think of the implementation to be similiar to Duolingo or some other learning site.
Users have all the standard generic user information but they also need to track how many points, words learned, percentage complete, and so on, that they have for each given lesson they've started.
Lessons have data like: words learned, total points, words to review, etc.
Picture
Example of what a user would see in the widget when they view a lesson they've already started...
So what's a good way to handle this? I feel that I will need at a minimum a collection for users and lessons, but where would I store that user specific data relating to lessons they've taken?
What I've thought of so far ...
// user collection
const UserSchema = new mongoose.Schema({
email: { type: String, required: true, unique: true },
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
firstName: { type: String },
lastName: { type: String },
gender: { type: String, enum: ['male', 'female', 'other'] },
admin: Boolean,
address: {
street: String,
city: String,
state: {
type: String,
uppercase: true,
required: true,
enum: statesArray,
},
zip: Number,
},
});
// lesson_results collection
const LessonResultsSchema = new mongoose.Schema({
user_id: Schema.Types.ObjectId,
results: [
{
id: Number,
lesson_id: Schema.Types.ObjectId,
pointsEarned: Number,
wordsLearned: Number,
wordsToPractice: [
{
id: Number,
correct: Number,
incorrect: Number,
bookmarked: Boolean,
},
],
},
],
});
// lesson collection
const LessonSchema = new mongoose.Schema({
title: String,
description: String,
totalPoints: Number,
totalWords: Number,
words: [
{
id: Number,
word: String,
points: Number
}
]
})
// if logged in
// find user in user collection
// find user's results in lessonsResults collection by using user_id
// iterate over each result to find their lesson & lesson's data
// combine data and send to frontend
// calculate percentage complete + other calculations
// render aggregate data on screen
I'm curious how you would resolve this.
Apologies if it's a bit long-winded! (+ hopefully the examples make sense)
You need to have the reference of user in LessonSchema, so that you can track how many lessons are taken by a user.
const LessonSchema = new mongoose.Schema({
user:{type:mongoose.Schema.Types.ObjectId,ref:'UserSchema',required:true},
title: String,
description: String,
totalPoints: Number,
totalWords: Number,
words: [
{
id: Number,
word: String,
points: Number
}
]
})
And you need to maintain a FLAG in LessonResultsSchema to track whether a user has completed that lesson or not. Once the lesson gets completed, you need to update the pointsEarned so that you can have the updated points data.
const LessonResultsSchema = new mongoose.Schema({
user_id: Schema.Types.ObjectId,
completed:{type:Boolean, default:0},
results: [
{
id: Number,
lesson_id: Schema.Types.ObjectId,
pointsEarned: Number,
wordsLearned: Number,
wordsToPractice: [
{
id: Number,
correct: Number,
incorrect: Number,
bookmarked: Boolean,
},
],
},
],
});

Mongoose Object Array won't work on Postman

After completing a course on MEAN Stack, I'm working on making my own webapp - a recipe page. I've designed my models, but when I try to fill the database with a new Recipe it just won't work. The main issue is the way I want to store ingredients, they'll be stored on one of the tables, then each recipe has its list of ingredients and amounts for each. For example, to make some toast you need, say "50 grs. of Butter and 4 slices of Bread". This is the Schema I'm using:
var RecipeSchema = Schema({
name: String,
desc: String,
author: { type: Schema.ObjectId, ref: 'User' },
category: { type: Schema.ObjectId, ref: 'Category' },
ingredients: [{ amount: String, ingredient: { type: Schema.ObjectId, ref: 'Ingredient' }}],
steps: [String],
image: String,
thumbnail: String,
portions: Number,
difficulty: Number,
cookingTime: Number,
comment: String
});
When I go in Postman and try to fill the "Toast Recipe" entry, I have the following:
name:Toast
desc:Toast is a common breakfast staple.
author:5cad791a7b2e651f7803f5de
category:5cb1ff8f484a172984178a97
ingredients:[{"amount": "4 slices", "ingredient": "5cb1ffdb484a172984178a98"}, {"amount": "35 grs.", "ingredient": "5cb2000d484a172984178a99"}]
steps:['Toast the bread in the oven.','Spread some butter on each toast.']
image:'null'
thumbnail:'null'
portions:1
difficulty:1
cookingTime:15
comment:'null'
But I keep getting a "cast Array" error. What could be the issue? Is it a problem with my model, with Postman, or with the way I'm sending the Array?
EDIT:
Apparently it was a problem whit the way I posted my arrays in Postman. After some more tests I managed to upload a full recipe in JSON format. The structure is correct (but what Juan suggests can be used too, to make the code cleaner).
I'am not completely sure, but when I worked with mongoose, inner objects had a new Schema object inside, in this case it would on ingredients
const IngredientSchema = new Schema({
amount: String,
ingredient: { type: Schema.ObjectId, ref:'Ingredient' }
});
const RecipeSchema = new Schema({
name: String,
desc: String,
author: { type: Schema.ObjectId, ref: 'User' },
category: { type: Schema.ObjectId, ref: 'Category' },
ingredients: [ IngredientSchema ],
steps: [String],
image: String,
thumbnail: String,
portions: Number,
difficulty: Number,
cookingTime: Number,
comment: String
});

Get documents with specific value in an array inside the document in mongodb

my document is as below
const mailSchema = new Schema ({
from: String,
to: [{
emailId: String,
status: Number
}],
cc: [{
emailId: String,
status: Number
}],
bcc: [{
emailId: String,
status: Number
}],
subject: String,
content: String,
status: Number,
createdBy: Schema.Types.ObjectId
}
How to retrieve document where 'to.emailid' contains a given value?
I have used below code but it is not working.
const emailtext = 'test#gmail.com'
MailSchema.find({'to.emailId': emailtext });
I think your schema is incorrect. what you want to do is to have a document that contain an object file. But what you did is a document with an array of file objects. so i think you should remove all the square bracket in the schema, then it should look like this.
//Mail Schema without array of objects.
const mailSchema = new Schema ({
from: String,
to: {
emailId: String,
status: Number
},
cc: {
emailId: String,
status: Number
},
bcc: {
emailId: String,
status: Number
},
subject: String,
content: String,
status: Number,
createdBy: Schema.Types.ObjectId
}
However if what you really want is an array of objects, then your query should also include the index of the array you want to get the emailId from.
Example.
MailSchema.find({'to[0].emailId': emailtext });

How to store properties with different languages in mongodb and mongoose

This is my schema:
var cvSchema = new Schema({
name: {type: String, required: true},
alias: {type: String, required: true, minlength: 6, maxlength: 6},
profitCentre: {type:Number, min:1000, max:9999},
city: String,
company: String,
profession: {
type: Schema.ObjectId,
ref: 'profession',
required: true
},
});
The profession property is a reference. The profession can have one value, but with several languages. Is there any best practice on how to do this?
I came up with two options:
var professionSchema = new Schema({
values: [
{
lang: {type: String, enum: ['sv', 'en']},
name: {type: String, required: true}
}
]
});
Option two: (en = english, sv = swedish):
var professionSchema = new Schema({
en: 'String',
sv: 'String'
});
The first one is more generic, but I find it difficult to run easy queries (populate etc) on it. It's easier to run queries with the second one. Is there a right or wrong way here?
I don't see either of these being right or wrong and think you should use the solution that fits best with what you are trying to accomplish.
You might even consider checking out this npm package to make things simpler.