У меня есть коллекция hero
, где каждый документ героя выглядит следующим образом:
{
_id:'the-name-of-the-hero',
name: 'Name of Hero',
(...), //other properties to this hero
relations: [
{
hero: 'the-id-of-another-hero',
relationType: 'trust'
},
{
hero: 'yet-another-id-of-another-hero',
relationType: 'hate'
}
]
}
relations.hero
указывает на _id
другого героя.Мне нужно было собрать больше информации о связанных героях, поэтому я использовал агрегат $lookup
, чтобы сопоставить каждого из них с коллекцией "hero", чтобы собрать ее name
(и другие данные, но проект упрощен для вопроса).Вот действующий в данный момент запрос:
let aggregate = db.collection('hero').aggregate([
// grabbing an specific hero
{ $match: { _id } },
//populate relations
{
$lookup: {
from: 'hero',
let: { letId: '$relations.hero' }, //create a local variable for the pipeline to use
// localField: "relations.hero", //this would bring entire hero data, which is unnecessary
// foreignField: "_id", //this would bring entire hero data, which is unnecessary
pipeline: [
//match each $relations.hero (as "$$letId") in collection hero's (as "from") $_id
{ $match: { $expr: { $in: ['$_id', '$$letId'] } } },
//grab only the _id and name of the matched heroes
{ $project: { name: 1, _id: 1 } },
//sort by name
{ $sort:{ name: 1 } }
],
//replace the current relations with the new relations
as: 'relations',
},
}
]).toArray(someCallbackHere);
Короче говоря, $lookup
на hero
коллекции с использованием pipeline
, которые соответствуют каждому из relations.hero
и возвращают только _id
и name
(который имеет настоящее имя для печати в пользовательском интерфейсе) и замените текущий relations
новым relations
, создав документ как:
{
_id:'the-name-of-the-hero',
name: 'Name of Hero',
(...), //other properties to this hero
relations: [
{
_id: 'the-id-of-another-hero',
name: 'The Real Name of Another Hero',
},
{
_id: 'yet-another-id-of-another-hero',
name: 'Yet Another Real Name of Another Hero',
}
]
}
Вопрос:
Что я могу добавить к конвейеру, чтобы он сливал подобранных героев с оригинальным relations
, чтобы иметь не только проецируемые _id
и name
, но и оригинальный relationType
?То есть получим следующий результат:
{
_id:'the-name-of-the-hero',
name: 'Name of Hero',
(...), //other properties to this hero
relations: [
{
_id: 'the-id-of-another-hero',
name: 'The Real Name of Another Hero',
relationType: 'trust' //<= kept from the original relations
},
{
_id: 'yet-another-id-of-another-hero',
name: 'Yet Another Real Name of Another Hero',
relationType: 'hate' //<= kept from the original relations
}
]
}
Я попытался экспортировать as: 'relationsFull'
, а затем попытался $push
с $mergeObjects
как часть следующего шага в агрегации, но безуспешно.Я пытался сделать то же самое, что и шаг конвейера (вместо нового шага агрегирования), но всегда получал relations
как пустой массив.
Как мне написать новый шаг агрегации для объединения старого relations
объекты с новым поиском relations
?
Примечание: рассмотрим MongoDB 3.6 или новее (то есть массив $unwind
не нужен, по крайней мере для $lookup
).Я запрашиваю использование драйвера Node.js, если эта информация имеет значение.