Как искать поле с массивом во вложенном поддокументе mongodb? - PullRequest
2 голосов
/ 07 мая 2019

Я пытаюсь получить некоторые данные поиска для встроенного массива в документе.

Вот пример данных:

{
      "_id": "58a4fa0e24180825b05e14e9",
      "fullname": "Test User",
      "username": "testuser"
      "teamInfo": {
          "challenges": [
              {
                  "levelId": "5e14e958a4fa0",
                  "title": "test challenge 1.1"
              },
              {
                  "levelId": "5e14e958a4fa0",
                  "title": "test challenge 1.2"
              },
              {
                  "levelId": "5e14e958a4fa1",
                  "title": "test challenge 2.1"
              }
          ]
      }
}

Как видите, teamInfo.challenges - это массив, содержащий поля levelId. Они указывают на поле _id в другой коллекции, называемой уровнями.

Но как мне получить ответ json, как это?

{
      "_id": "58a4fa0e24180825b05e14e9",
      "fullname": "Test User",
      "username": "testuser"
      "teamInfo": {
          "challenges": [
              {
                  "levelInfo": {
                      "name": "Level 1"
                  },
                  "title": "test challenge 1.1"
              },
              {
                  "levelInfo": {
                      "name": "Level 1"
                  },
                  "title": "test challenge 1.2"
              },
              {
                  "levelInfo": {
                      "name": "Level 2"
                  },
                  "title": "test challenge 2.1"
              }
          ]
      }
}

Я пытаюсь использовать раскрутку, проект и группу. Но я так растерялся.

const user = await User.aggregate([
                {
                    $match: {_id: new mongoose.Types.ObjectId(req.user.userId)}
                },
                {
                    $lookup: {
                        from: 'levels',
                        localField: 'teamInfo.challenges.levelId',
                        foreignField: '_id',
                        as: 'challLevelInfo'
                    }
                },
                {
                    $group: {
                        _id: "$_id",
                        ........IM CONFUSED HERE........
                    }
                }
]);

1 Ответ

1 голос
/ 07 мая 2019

Вы можете использовать конвейер поиска для обработки вложенного поиска

const pipeline = [
   {
     $match: {_id: new mongoose.Types.ObjectId(req.user.userId)}
   },
   {
     $lookup: {
       from: 'levels',
       let: { level_id: "$teamInfo.challenges.levelId" },
       pipeline: [
         {
           $match: {
             $expr: {
               $eq: ["$_id", "$$level_id"]
             }
           }
         },
         {
           $lookup: {
             from: '<level collection>',
             localField: "levelId",
             foreignField: "_id",
             as: "levelInfo"
           }
         },
         {
           $project: {
             levelInfo: {
               name: "$levelInfo.name"
             }
             title: 1
           }
         }
       ],
       as: "challenges"
     },

   },
   { $project: {
     _id: 1,
     fullname: 1,
     username: 1,
     teamInfo: {
       challenges: "$challenges"
     }
   }}
]

const result = await User.Aggregate(pipeline)

надеюсь, что это поможет!

...