Почему мой запрос драйвера mongodb nodejs на aggregate $lookup не возвращает результаты, как ожидалось

#javascript #node.js #mongodb #aggregation-framework

Вопрос:

У меня есть две коллекции: users и roles

Пользователям назначено множество ролей:

 {
    _id : 61582a79fd033339c73ee290
    roles:[615825966bc7d715021ce8fc, 615825966bc7d715021ce8fd]
}
 

роли:

 [
   {
     _id: 615825966bc7d715021ce8fc
     name: 'user',
   },
   {
     _id: 615825966bc7d715021ce8fd
     name: 'admin',
   },
]
 

Как вы можете видеть, у пользователя есть массив идентификаторов объектов, соответствующих ролям.

У меня есть агрегированный запрос $lookup, в котором я пытаюсь вернуть всех пользователей с заполненными ролями:

 dbManager.aggregate = async () => {
    let a = dbInstance.collection('users').aggregate(
        [
            {
                $lookup:
                {
                    from: 'roles',
                    localField: 'roles',
                    foreignField: '_id',
                    as: 'user_roles'
                }
            }
        ]
    )
    console.log('a:::::::', a)
}
 

Когда я запускаю этот запрос: dbManager.aggregate() , я получаю очень большой объект, и я нигде не вижу информации о пользователе и не знаю, как ее извлечь. Согласно документации, это должно возвращать информацию, которую я запрашиваю. Вот первые несколько полей того, что он возвращает, так как я не хочу перегружать огромный объект:

 AggregationCursor {
  _events: [Object: null prototype] {},
  _eventsCount: 0,
  _maxListeners: undefined,
 [Symbol(kCapture)]: false,
 [Symbol(topology)]: Topology {
    _events: [Object: null prototype] {
      topologyDescriptionChanged: [Array],
    }
  ...
}
 

Что я делаю не так?

Комментарии:

1. поставить await перед запросом let a = await dbInstance.collection('users').aggregate(

2. Пробовал это раньше. Не повезло. Спасибо, что ответили!

3. В соответствии с этой собственной документацией node mongo , он вернет класс экземпляра курсора агрегации, вы можете поместить функцию обратного вызова в качестве последнего параметра в агрегатной функции.

Ответ №1:

По-видимому, я должен позвонить .toArray , который возвращает обещание, которое разрешает данные:

 dbManager.aggregate = async () => {
    let a = await dbInstance.collection('users').aggregate(
        [
            {
                $lookup:
                {
                    from: 'roles',
                    localField: 'roles',
                    foreignField: '_id',
                    as: 'user_roles'
                }
            }
        ]
    )
     .toArray().then(data => data)
     .catch(e => console.log(e))
    console.log('a:::::::', a)
}
 

Это своего рода отстой, что нигде на странице не говорится об этом в документации MongoDB, но я рад, что смог найти решение!