【问题标题】:Compare arrays and filter, using MongoDB aggregation比较数组和过滤器,使用 MongoDB 聚合
【发布时间】:2021-04-07 22:43:50
【问题描述】:

对于我的数据库,我编写了以下管道:

let orders = await Order.aggregate(
        {
          $unwind: "$candidate",
        },
        {
          $lookup: {
            from: "groups",
            localField: "candidate.groupId",
            foreignField: "_id",
            as: "groupData",
          },
        },
        {
          $lookup: {
            from: "users",
            let: {
              id: "$candidate.groupId",
            },
            pipeline: [
              { $match: { groupId: { $ne: null } } },
              {
                $match: {
                  $expr: { $in: ["$$id", "$groupId"] },
                },
              },
              { $project: { name: 1, email: 1, _id: 1 } },
            ],
            as: "members",
          },
        },
        { $match: { "members._id": new ObjectId(req.userId) } },
        {
          $lookup: {
            from: "users",
            let: { ids: "$candidate.autonomousId" },
            pipeline: [
              {
                $match: {
                  $expr: { $in: ["$_id", "$$ids"] },
                },
              },
              { $project: { name: 1, email: 1, _id: 1 } },
            ],
            as: "candidate",
          },
        },
        {
          $project: {
            groupData: 1,
            members: 1,
            candidate: 1,
            stillAvailable: 1,
            _id: 0,
          },
        }
      ).toArray();

输出是预期的......

{ candidate:
    [ { _id: 601817dc2eeecd17db3a68f6,
        name: 'Maria' },
      { _id: 601817ef2eeecd17db3a68f7,
        name: 'Jose' } ],
   groupData:
    [ { _id: 606632403fffb851b8c41d12,
        name: 'Giraia' } ],
   members:
    [ { _id: 601817dc2eeecd17db3a68f6,
        name: 'Maria' },
      { _id: 601817ef2eeecd17db3a68f7,
        name: 'Jose' },
      { _id: 60182cbb2b654330d2458f89,
        name: 'Jonas'} ] } 

管道的最后一步是比较数组,过滤哪些members 不是candidates,然后将它们添加到数组stillAvailable。我尝试了很多方法,但我无法通过聚合实现我的目标。我能找到的唯一解决方案是在我的后端处理不完整管道的结果。代码是:

  orders.forEach(
    (order) =>
      (order.stillAvailable = order.members.filter(
        (autonomous) =>
          !order.candidate.some((el) => {
            return el._id.toString() === autonomous._id.toString();
          })
      ))
  );

这样,我达到了预期的输出......

 { candidate:
    [ { _id: 601817dc2eeecd17db3a68f6,
       name: 'Maria' },
      { _id: 601817ef2eeecd17db3a68f7,
       name: 'Jose' } ],
   groupData:
    [ { _id: 606632403fffb851b8c41d12,
        name: 'Giraia' ],
   members:
    [ { _id: 601817dc2eeecd17db3a68f6,
        name: 'Maria' },
      { _id: 601817ef2eeecd17db3a68f7,
        name: 'Jose' },
      { _id: 60182cbb2b654330d2458f89,
        name: 'Jonas' ],
   stillAvailable:
    [ { _id: 60182cbb2b654330d2458f89,
        name: 'Jonas' ] }

问题是为了更好地划分我的代码,有必要将最后一步(在我的后端使用 javascript 完成)作为管道上的又一步实现。有谁知道如何达到这个目标?

【问题讨论】:

    标签: javascript mongodb aggregation-framework


    【解决方案1】:

    在我在这里写下问题之后,不知何故,这个想法结构更好,我使用$map 和更高级别的$lookup 实现了结果!我把答案记录在这里,以防有人遇到同样的问题。

      let orders = await Order.aggregate(
        {
          $unwind: "$candidate",
        },
        {
          $lookup: {
            from: "groups",
            localField: "candidate.groupId",
            foreignField: "_id",
            as: "groupData",
          },
        },
        {
          $lookup: {
            from: "users",
            let: {
              id: "$candidate.groupId",
            },
            pipeline: [
              { $match: { groupId: { $ne: null } } },
              {
                $match: {
                  $expr: { $in: ["$$id", "$groupId"] },
                },
              },
              { $project: { name: 1, email: 1, _id: 1 } },
            ],
            as: "members",
          },
        },
        { $match: { "members._id": new ObjectId(req.userId) } },
        {
          $lookup: {
            from: "users",
            let: { ids: "$candidate.autonomousId" },
            pipeline: [
              {
                $match: {
                  $expr: { $in: ["$_id", "$$ids"] },
                },
              },
              { $project: { name: 1, email: 1, _id: 1 } },
            ],
            as: "candidate",
          },
        },
        {
          $project: {
            groupData: 1,
            members: 1,
            candidate: 1,
            _id: 0,
            stillAvailable: {
              $setDifference: [
                {
                  $map: {
                    input: "$members",
                    as: "member",
                    in: "$$member._id",
                  },
                },
                {
                  $map: {
                    input: "$candidate",
                    as: "el",
                    in: "$$el._id",
                  },
                },
              ],
            },
          },
        },
        {
          $lookup: {
            from: "users",
            let: {
              ids: "$stillAvailable",
            },
            pipeline: [
              {
                $match: {
                  $expr: { $in: ["$_id", "$$ids"] },
                },
              },
              { $project: { name: 1, email: 1, _id: 1 } },
            ],
            as: "stillAvailable",
          },
        }
      ).toArray();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-27
      • 1970-01-01
      • 2021-07-26
      • 2020-03-29
      • 1970-01-01
      • 2021-04-02
      • 2019-03-13
      相关资源
      最近更新 更多