This question already has answers here:
How to query nested objects?
(3 answers)
Closed 3 years ago.
I am trying to search through all the comments and return all comments created by a specific user from my mongodb how ever when i try to search the array returned is empty.
I have tried :
Comment.find({author: {$elemMatch: {username: req.params.username}}}, (err, foundComments) => {
// Code goes here
});
The Mongoose Comment Schema:
const mongoose = require('mongoose');
const commentSchema = new mongoose.Schema({
text: String,
discussion:[{
type: mongoose.Schema.Types.ObjectId,
ref: 'Comment',
}],
createdAt: {
type: Date,
default: Date.now,
},
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
},
username: 'String',
avatar: {
image: String,
imageId: String,
},
},
likes: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
}],
dislikes: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
}],
});
module.exports = mongoose.model('Comment', commentSchema);
When I run it I am expecting foundComments to be an array [ array of comments ] but I just get an empty array [].
Comment.find({"author.username":req.params.username});
Comment.find({"username": req.params.username},{"discussion":1,"_id":0})
Related
This question already has answers here:
Remove multiple documents from mongo in a single query
(5 answers)
Cascade style delete in Mongoose
(5 answers)
Closed 4 years ago.
The scenario is I have a User model that has an array called filedLeaves which contains ObjectId's that are referenced on another collection. What I want to do is also remove those ObjectIds from its collection once that specific user is removed.
Here's my User Model
var schema = new Schema({
fullName: {
type: String,
required: true,
unique: true
},
leaveCredits: {
type: Number
},
filedLeaves: [{
type: Schema.Types.ObjectId,
ref: 'Leave'
}]
}, {
usePushEach: true
});
And my Leave Model
var schema = new Schema({
userId: {
type: Schema.Types.ObjectId,
ref: 'User'
},
status: {
type: String,
required: true
},
start: {
type: String,
required: true
},
end: {
type: String,
required: true
},
type: {
type: String,
required: true
}
});
I tried this on my User model but it doesn't seem to work.
schema.post('remove', function (user) {
user.filedLeaves.forEach(id => {
Leave.findByIdAndRemove(id)
});
});
so each comment is its own document. is this how i nest comments in each other, when a user replies to one?
and if something is nested lets say as much as 10 deep in replies, how do I do a for loop to loop through it all?
var RK = mongoose.Schema.ObjectId;
var CommentSchema = Schema({
body: {type: String},
chapterId: {type: RK, ref: 'Chapter'},
by: {type: RK, ref: 'User'},
children: [{
type: RK,
ref: 'Comment'
}]
}, {timestamps: true});
let dependencySchema = mongoose.Schema({
dependencyComment: {
type: mongoose.Schema.Types.ObjectId,
required: false
},
dependencyAuthor: {
type: mongoose.Schema.Types.ObjectId,
required: false
}
});
let CommentSchema = mongoose.Schema({
//Rest of you schema
children: [{
type: mongoose.Schema.Types.ObjectId,
ref: [dependencySchema]
}]
}, {timestamps: true});
this way you nest the comment to N-th Level
I want to populate the fields of a subdocument, which is a discriminated element of a common Schema (Notificationable discriminated into Message or FriendRequest).
This question is quite similar to this one: mongoosejs: populating an array of objectId's from different schemas, which was not solved two years ago. Since mongoose evolved, and discriminator also, I am asking the question again.
What I have tried so far:
Notification.find({_id: 'whatever'})
.populate({
path: 'payload',
match: {type: 'Message'},
populate: ['author', 'messageThread']
})
.populate({
path: 'payload',
match: {type: 'FriendRequest'},
populate: ['to', 'from']
})
.exec();
This does not work, because the path is the same.
So I tried:
Notification.find({_id: 'whatever'})
.populate({
path: 'payload',
populate: [
{
path: 'messageThread',
match: {type: 'Message'},
},
{
path: 'author',
match: {type: 'Message'},
},
{
path: 'from',
match: {type: 'FriendRequest'},
},
{
path: 'to',
match: {type: 'FriendRequest'},
},
]
})
.exec();
Which does not work either, maybe because the match is executed in the subdocument and thus does not have a field type.
Is there any solution for this?
Here are my (main) models, I did not provide User or MessageThread.
The main document:
const NotificationSchema = new Schema({
title: String,
payload: {
type: Schema.Types.ObjectId,
ref: 'Notificationable'
});
mongoose.model('Notification', NotificationSchema);
The payload Parent schema
let NotificationableSchema = new Schema(
{},
{discriminatorKey: 'type', timestamps: true}
);
mongoose.model('Notificationable', NotificationableSchema);
And the two discriminated possibilities:
let Message = new Schema({
author: {
type: Schema.Types.ObjectId,
ref: 'User'
},
messageThread: {
type: Schema.Types.ObjectId,
ref: 'MessageThread'
}
}
Notificationable.discriminator('Message', Message);
And:
let FriendRequest = new Schema({
from: {
type: Schema.Types.ObjectId,
ref: 'User'
},
to: {
type: Schema.Types.ObjectId,
ref: 'User'
}
}
Notificationable.discriminator('FriendRequest', FriendRequest);
The problem is:
I have a collection of photos schema and likes schema, and inside photos there is an array of like ObjectIds called likeArray which is used to populate data from likes colletion.
But when i delete a like from likes collection, the ObjectId of that like in the likeArray still exists.
I tried to find the index of like._id in the likeArray and use likeArray.splice(index, 1) but couldn't work.
Can someone know the solution?
Here's the photo schema:
var Photo = mongoose.model('Photo', new mongoose.Schema({
photo_url: String,
photo_description: String,
user:{
id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
},
username: String,
profile_photo: String
},
comments: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'comment'
}
],
likes: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'like'
}
],
created_at: {type: Date, default: Date.now}
}));
Here's the Like schema:
var Like = mongoose.model('Like', new mongoose.Schema({
user_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
},
photo_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'photo'
},
created_at: {type: Date, default: Date.now}
}));
Instead of splice you can use $pull operator. Here's how it'd look in mongo shell.
db.likes.remove({_id: like_oid});
db.photos.update({likes: like_oid}, {$pull: {likes: like_oid}}, { multi: true });
I'm trying to populate my Thread schemas GET response with all the comments related that that specific thread. I've specified a path within the Thread model to accept an array of Comments that I'll then populate when I request a thread, but it's continuing to be empty.
I'm not sure if I then need to push all the comments into the thread, but I think with the way I'm doing it, it's not required? I'm using Mongoose 4.4.19. I've followed along with the docs but still can't figure out where I've gone wrong.
Thread Schema:
const threadSchema = new Schema({
user: {
type: Schema.ObjectId,
ref: 'User',
required: true
},
title: {
type: String
},
content: {
type: String
},
category: {
type: String
},
comments: [{
type: Schema.ObjectId,
ref: 'Comment'
}]
}, {
timestamps: true
})
Comment Schema:
const commentSchema = new Schema({
user: {
type: Schema.ObjectId,
ref: 'User',
required: true
},
thread: {
type: Schema.ObjectId,
ref: 'Thread',
required: true
},
content: {
type: String
}
}, {
timestamps: true
})
Handles get requests:
export const index = ({ querymen: { query, select, cursor } }, res, next) =>
Thread.find(query, select, cursor)
.populate('user comments')
.then(threads => threads.map(thread => thread.view()))
.then(success(res))
.catch(next)