Вы можете начать с планирования того, что вы хотите сделать.Например, вы можете попробовать это:
План
- отмена комментариев
- проецирование полей, которые вы хотите
- сгруппировать это вместе
- (необязательно) очистка
Реализация
- Размотка все комментарии
Таким образом, этапы будут:
const unwind = {
$unwind: '$Comments',
};
Это приводит к дублированию - или, скорее, к умножению - ваших документов на столько, сколько у вас есть комментариев.
Проект
Теперь Проект Имя / идентификатор комментатора, если необходимо:
const project = {
$project: {
PostId: 1,
CommentId: '$Comments._id',
CommentedBy: '$Comments.commentedBy.Name',
},
}
Теперь для каждого комментария у вас есть документ: { PostId, CommentId, CommentedBy }
.
Сгруппируйте их снова.
Теперь вы можете группировать свои комментарии обратно, сгруппировать их по PostId
:
const group = {
$group: {
_id: '$PostId',
PostId: '$PostId',
Comments: {
$push: {
_id: '$CommentId',
CommentedBy: '$CommentedBy',
},
},
},
};
Теперь вы будетеполучите ваши документы так:
{
_id: '<PostID>',
PostId: '<PostID>',
Comments: [
{ _id: '<CommentId>', CommentedBy: '<username>' },
],
}
(опционально) очистка
Вы заметите, что у вас есть дополнительный верхний уровень _id
, вы можете избавиться от него в другой $project
фазе:
const cleanup = { $project: { _id: 0, ... } };
Итак, вся ваша труба теперь проста:
db.getCollection('posts')
.aggregate([
unwind,
project,
group,
cleanup,
]);
Я опустил шаблон и набираю здесь без MongoDB, так что вы можете проверить код дважды.(Возможно, вы все равно захотите сделать это с помощью кодов из internetz.)