I'm working on a feature that recursively looks up a thread of comments using $graphLookUp, and I almost have it. (albeit in a somewhat convoluted way but it is working!)
The last step I need is the following:
instead of having the nested posteriorThread as a property of the root array ($$ROOT), just merge it onto the root itself.
const posteriorThread = await Comment.aggregate([
{
$match: {
_id: post.threadDescendant
}
},
{
$graphLookup: {
from: 'baseposts',
startWith: '$threadDescendant',
connectFromField: 'threadDescendant',
connectToField: '_id',
as: 'posteriorThread'
}
},
{
$unwind: '$posteriorThread'
},
{
$sort: { 'posteriorThread.depth': 1 }
},
{
$group: {
_id: '$_id',
posteriorThread: { $push: '$posteriorThread' },
root: { $first: '$$ROOT' }
}
},
{
$project: {
'root.posteriorThread': 0
}
},
{
$replaceRoot: {
newRoot: {
$mergeObjects: [
{
posteriorThread: '$posteriorThread'
},
'$root'
]
}
}
}
]);
OUTPUT: posteriorThread
[
{
_id: '5f7eab40575e6fc56ee07604',
onModel: 'BasePost',
depth: 1,
user: '5f5da45245c07cc06e51b09f',
text: 'thread 0',
isThread: true,
threadDescendant: '5f7eabad575e6fc56ee07607',
posteriorThread: [
{
_id: '5f7eabad575e6fc56ee07607',
onModel: 'Comment',
depth: 2,
user: '5f5da45245c07cc06e51b09f',
text: 'thread 1',
isThread: true,
threadDescendant: '5f7eac82575e6fc56ee07609'
},
{
_id: '5f7eac82575e6fc56ee07609',
onModel: 'Comment',
depth: 3,
user: '5f5da45245c07cc06e51b09f',
text: 'thread 2',
isThread: true
}
]
}
];
OUTPUT: posteriorThread
[
{
_id: '5f7eab40575e6fc56ee07604',
onModel: 'BasePost',
depth: 1,
user: '5f5da45245c07cc06e51b09f',
text: 'thread 0',
isThread: true,
threadDescendant: '5f7eabad575e6fc56ee07607'
},
{
_id: '5f7eabad575e6fc56ee07607',
onModel: 'Comment',
depth: 2,
user: '5f5da45245c07cc06e51b09f',
text: 'thread 1',
isThread: true,
threadDescendant: '5f7eac82575e6fc56ee07609'
},
{
_id: '5f7eac82575e6fc56ee07609',
onModel: 'Comment',
depth: 3,
user: '5f5da45245c07cc06e51b09f',
text: 'thread 2',
isThread: true
}
];
I could accomplish this after the aggregation in regular js, but I would prefer to do it all in the aggregation.
The part that needs to be replaced is the mergeObjects bit and replaced with something else or the group aggregation and taking a different strategy, but I'm not sure what to put in it's place.
Also, if you have any other suggestions to make this cleaner, I'm all ears.
Thanks in advance.
Its really challenging. Atleast for me. And really very interesting case. Lets try my solution. Hope it works..
db.test.aggregate([
// PREVIOSU STEPS YOU ALREADY DID
{
$group: {
_id: "$_id",
items: {$push: "$$ROOT"},
subItems: {$first: "$posteriorThread"}
}
},
{
$project: {
"items.posteriorThread": 0
}
},
{
$addFields: {
allItems: {
$concatArrays: ["$items", "$subItems"]
}
}
},
{
$group: {
_id: null,
mergedItems: {$push: "$allItems"}
}
},
{
$unwind: "$mergedItems"
},
{
$unwind: "$mergedItems"
},
{
$replaceRoot: {
newRoot: "$mergedItems"
}
}
])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With