I'm wondering if you can dynamically deep populate with MongoDB, specifically I'm using mongoose on an express app. I'm trying to build a basic reddit clone. On my Post model, I'm trying to create a reply chain. Replies could become nested, as someone could reply to a reply of a reply. Can I populate down that reply chain? I can only figure out how to populate the first layer of replies. Based on reading the documentation and looking at other anwsers on stack overflow I don't think this is possible, but wanted to put the question out there before I remodeled my data. Here is my Post Model:
const postSchema = new mongoose.Schema(
{
content: {
type: String,
required: [true, 'A post can not be empty'],
},
thread: {
type: mongoose.Schema.ObjectId,
ref: 'Thread',
},
isReply: {
type: Boolean,
default: false,
},
parentPost: {
type: mongoose.Schema.ObjectId,
ref: 'Post',
},
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
);
postSchema.virtual('replies', {
ref: 'Post',
foreignField: 'parentPost',
localField: '_id',
});
And the thread handler where I'm doing the query and trying to populate the reply chain:
exports.getThread = factory.getOne(Thread, 'thread', {
path: 'posts',
// Deep populate the replies from each post
populate: { path: 'replies' },
});
// This is the factory getOne function
exports.getOne = (Model, modelName, popOptions) =>
catchAsync(async (req, res, next) => {
const query = popOptions
? Model.findById(req.params.id).populate(popOptions)
: Model.findById(req.params.id);
const doc = await query;
if (!doc)
return next(
new AppError(`No ${modelName} could be found with that id`, 404)
);
res.status(200).json({
status: 'success',
data: { [modelName]: doc },
});
});
The desired behaviour is not integrated into mongoose.
I would also advice against a data-structure that makes this necessary. Did you consider other document tree structures (you can find plenty of examples on here or check out the mongodb docu). I find trees with parent references most useful for comments.
But back to recursive population:
Generally you wouldn't want a query that can return unpredictable amounts of data. So only do this if you otherwise limit the amount of returned docs!
There is another question providing a few examples of custom implementations of recursive relationship population (link)