如何获取满足匹配object的关联文档

How to get associated document who satisfy match object

在下面的查询中,我想获取所有经过验证的学生及其相关会议。但试图获取所有即将举行的会议,这意味着会议至少有一个未来的日期时间。我的书面查询获取了所有经过验证的学生,但也获取了学生的所有会议,包括过去的会议。我希望一个学生只有在有任何即将举行的会议时才会被提取,并且只在返回协会中提取即将举行的会议。我想根据最近的会议对 objects 的客户端数组进行排序任何帮助将不胜感激

     let aggregateDataQuery = [
        {
          $lookup: {
            from: 'meetup',
            localField: '_id',
            foreignField: 'studentId',
            as: 'meetup',
          },
        },
        {
          $project: {
            firstName: 1,
            lastName: 1,
            email: 1,
            meetup: {
              _id: 1,
              startTime: 1,
            },
          },
        },
      ];

      const [result, err] = await of(
        Student.aggregate([
          ...aggregateDataQuery,
          { $match: { 
          verified: true,
              'meetup.startTime': { '$gte': 2021-09-10T08:41:15.746Z }
           } 
          },
          {
            $facet: {
              data: [
                { $sort: sortBy },
                { $skip: skip },
                { $limit: recordLimit },
              ],
              count: [
                {
                  $count: 'count',
                },
              ],
            },
          },
        ])
      );

根据两个 collection 的规模,我建议从 meetings collection 开始查询,因为这样可以更好地利用会议时间的索引(想象一下没有未来的会议,在目前的方法中你仍然匹配并查找整个学生 collection)。

但是您当前的方法很好,只需要一个小的调整,我们需要过滤掉“旧的”会议,为此让我们使用 join condition lookup syntax

现在您的新查找阶段将如下所示:

{
  "$lookup": {
    "from": "meetup",
    "let": {
      studentId: "$_id"
    },
    "pipeline": [
      {
        $match: {
          $expr: {
            $and: [
              {
                $eq: [
                  "$$studentId",
                  "$studentId"
                ],
                
              },
              {
                $gt: [
                  "$startTime",
                  "$$NOW"
                ],
                
              }
            ]
          }
        }
      },
      {
        $project: {
          _id: 1,
          startTime: 1,
          
        }
      }
    ],
    "as": "meetup"
  }
}

Mongo Playground

并且您需要的行为将按预期与管道的其余部分一起工作。

您可以将 $match 查询更改为:

{ 
  $match: { 
     verified: true,
     'meetup.0': {$exists: true}
  } 
}