簡體   English   中英

比較 arrays 和過濾器,使用 MongoDB 聚合

[英]Compare arrays and filter, using MongoDB aggregation

對於我的數據庫,我編寫了以下管道:

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();

output 是預期的……

{ 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'} ] } 

管道的最后一步是比較 arrays,過濾哪些members不是candidates成員並將它們添加到數組stillAvailable中。 我嘗試了很多方法,但我無法通過聚合實現我的目標。 我能找到的唯一解決方案是在我的后端處理不完整管道的結果。 代碼是:

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

有了這個,我達到了預期的 output ......

 { 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 完成)作為管道上的另一個步驟。 有誰知道如何達到這個目標?

在我在這里寫下問題之后,不知何故,這個想法結構更好,我使用$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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM