Mongoose nested array update - mongodb

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)
})

Related

mongoose comments and replies schema

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}
]
}]

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,
},
],
},
],
});

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 do you change a fieldName via mongoose method + change it in schema?

I have a schema like this:
const StorySchema = new Schema({
authorId: String,
title: String,
longUrl: String,
shortUrl: String,
comment: String,
category: String,
author: String,
date: { type: Date, default: Date.now, index: true },
votes: { type: Number, default: 1, index: true },
});
I want to change the votes field on the schema to be called votesCount and at the same time I want to actually change the schema.
Would I just do these in the same file?
const StorySchema = new Schema({
authorId: String,
title: String,
longUrl: String,
shortUrl: String,
comment: String,
category: String,
author: String,
date: { type: Date, default: Date.now, index: true },
votesCount: { type: Number, default: 1, index: true },
});
const StoryModel = mongoose.model('story', StorySchema);
StoryModel.update({}, { $rename: { votes: 'votesCount' } }, { multi: true, strict: false }, function(err, blocks) { });
Or do I not do this at all in the code? I have never dealt with database schema changes, so I'm not sure how / where to apply schema changes.
Make your changes in the Schema and the controller, as whatever name you use in your Schema field should also tally with the one in your Controller.
Eg.
const StorySchema = new Schema({
authorId: String,
title: String,
longUrl: String,
shortUrl: String,
comment: String,
category: String,
author: String,
date: { type: Date, default: Date.now, index: true },
votesCount: { type: Number, default: 1, index: true },
});
In your controller
let form = {
authorId:req.body.*****,
title:req.body.*****,
longUrl:req.body.*****,
shortUrl:req.body.*****,
comment:req.body.*****,
category:req.body.*****,
author:req.body.*****,
date:req.body.*****,
votesCount:req.body.*****
};
Note: the main point am trying to make here is that, the very name you used in the Schema should also the the same name you're gonna use for your controller.
I hope this is answers your question.
best use updateMany as
db.students.updateMany( {}, { $rename: { "nmae": "name" } } )
and change in your controller or directly replace previous field name to new field name where ever possible.
My Suggestion is better u first replace in controller or your project and if your project running in production update your new controller than u replace the field name using $rename

Syntax error Unexpected token ILLEGAL Mongo Console

I'm trying to remove a document from an array threads that is a field in the collection's head document.
In Mongodb console I write following query:
db.inboxes.update({}, { $pull: {threads: {"_id":ObjectId(”5550b41ce7c33013c8000006”)}}})
But I keep getting:
Unexpected token ILLEGAL
It's driving me crazy. The Collection's schema is as following:
var inboxSchema = mongoose.Schema({
user: {
type: mongoose.Schema.ObjectId,
ref: 'userSchema',
required: true
},
threads: [{
name: String,
guid: String,
with: {
_id: {
type: mongoose.Schema.ObjectId,
ref: 'userSchema'
},
name: {
username: String,
firstname: String,
lastname: String
},
email: {
type: String,
match: /\S+#\S+\.\S+/
}
},
messages: [{
heading: String,
sent: {
type: Date,
default: Date.now
},
from: {
type: mongoose.Schema.ObjectId,
ref: 'userSchema'
},
to: {
type: mongoose.Schema.ObjectId,
ref: 'userSchema'
},
body: String
}],
updated: {
type: Date,
default: Date.now
},
unreadMessage: Boolean
}]
});
Take a look at your query
db.inboxes.update({}, { $pull: {threads: {"_id":ObjectId(”5550b41ce7c33013c8000006”)}}})
in ObjectId argument you have wrong quote marks ” instead of ". Replace them and you will get rid of the error :)