Mongoose 加入两个集合并获取两个属性中的引用数据 [英] Mongoose join two collections and get referenced data in two properties

查看:62
本文介绍了Mongoose 加入两个集合并获取两个属性中的引用数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一个简单的关注朋友功能.

I'm doing a simple follow friend functionality.

请看下面我的代码:

以下架构:

{
 "userId": { type: String },
 "followers": [{ "followerId": type: String }],
 "followings": [{ "followingId": type: String }], 
}

用户架构:

{
 "fullName": { type: String } 
}

注意:用户 8 有 1 个关注者和 2 个关注者.

Note: user 8 has 1 follower and 2 followings.

现在,我的预期输出应该是这样的:

Now, my expected output should be like this:

        "userId": 8,
        "followers": [
            {
                "followerId": 4,
                "fullName": "Rose Marriott",
            },
            {
                "followerId": 5,
                "fullName": "James Naismith",
            }
        ],
        "followings": [
            {
                "followingId": 1,
                "fullName": "Russell Oakham",
            },
            {
                "followingId": 5,
                "fullName": "James Naismith",
            }
        ]

这是我目前尝试过的:

 db.followings.aggregate([
 { $unwind: "$followers" },
    {
        $lookup: {
            from: "users",
            localField: "followers.followerId",
            foreignField: "_id",
            as: "users"
        }
    },
    { 
        $addFields: 
        { 
            users: { $arrayElemAt: ["$users", 0] },
        },
    },
    { $unwind: "$followings" },
    {
        $lookup: {
          from: "users",
          localField: "followings.followingId",
          foreignField: "_id",
          as: "users2"
        }
    },
    { 
        $addFields: 
        { 
            users2: { $arrayElemAt: ["$users2", 0] },
        },
    },
    { $match: {"userId": mongoose.Types.ObjectId(userId) } },
    {
        $group: {
            _id: "$_id",
            userId: { $first: "$userId" },
            followers: {
                $push: {
                    followerId: "$followers.followerId",
                    fullName: "$users.fullName",
                }
            },
            followings: {
                $push: {
                    followingId: "$followings.followingId",
                    fullName: "$users2.fullName",
                }
            }
        }
      }
  ]);

但我有 2 个关注者和 2 个关注者.我想知道是什么导致了这个问题.感谢任何帮助.谢谢!

But I'm getting 2 followers and 2 followings. I wonder what's causing this issue. Appreciate any help. Thanks!

推荐答案

你可以试试,

  • $addFields 生成一个名为 userIds 的唯一数组,形成数组 followersfollowings, $setUnion 获取唯一 ID,
  • $lookup 与用户集合
  • $project 显示字段,
    • followers 获取 fullName、$map 以迭代 followers 循环并使用 $reduce 从用户数组中获取 followerId 的名称$cond
    • followings 获取 fullName、$map 以迭代 followings 的循环并使用 $reduce 从用户数组中获取 followingId 的名称$cond
    • $addFields to make a unique array called userIds form both arrays followers and followings, $setUnion to get unique ids,
    • $lookup with users collection
    • $project to show fields,
      • followers get fullName, $map to iterate loop of followers and get the name of followerId from users array using $reduce and $cond
      • followings get fullName, $map to iterate loop of followings and get the name of followingId from users array using $reduce and $cond
      db.followings.aggregate([
        {
          $addFields: {
            userIds: {
              $setUnion: [
                {
                  $map: {
                    input: "$followers",
                    in: "$$this.followerId"
                  }
                },
                {
                  $map: {
                    input: "$followings",
                    in: "$$this.followingId"
                  }
                }
              ]
            }
          }
        },
        {
          $lookup: {
            from: "users",
            localField: "userIds",
            foreignField: "_id",
            as: "users"
          }
        },
        {
          $project: {
            userId: 1,
            followers: {
              $map: {
                input: "$followers",
                as: "f",
                in: {
                  $mergeObjects: [
                    "$$f",
                    {
                      fullName: {
                        $reduce: {
                          input: "$users",
                          initialValue: "",
                          in: {
                            $cond: [
                              { $eq: ["$$this._id", "$$f.followerId"] },
                              "$$this.fullName",
                              "$$value"
                            ]
                          }
                        }
                      }
                    }
                  ]
                }
              }
            },
            followings: {
              $map: {
                input: "$followings",
                as: "f",
                in: {
                  $mergeObjects: [
                    "$$f",
                    {
                      fullName: {
                        $reduce: {
                          input: "$users",
                          initialValue: "",
                          in: {
                            $cond: [
                              { $eq: ["$$this._id", "$$f.followingId"] },
                              "$$this.fullName",
                              "$$value"
                            ]
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      ])
      

      游乐场

      这篇关于Mongoose 加入两个集合并获取两个属性中的引用数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆