Mongoose Get Mutual Followers/Following

I have been working on a simple followers/following app. This question is a continuation of my previous question here. This is what I’ve tried so far:

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"
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
])

Here’s the Mongo playground

Now, what I want to achieve is to display 2 boolean fields namely isFollowed for Followings and isFollowing for Followers array. Is this possible? I would gladly appreciate any help. Thanks!

Hi @nirmamalen

Welcome to MongoDB community !

I am not sure I fully understood the placing of this filed but I think the following command:

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"
                      ]
                    }
                  }
                },
                isFollowing: true
              }
            ]
          }
        }
      },
      followings: {
        $map: {
          input: "$followings",
          as: "f",
          in: {
            $mergeObjects: [
              "$$f",
              {
                fullName: {
                  $reduce: {
                    input: "$users",
                    initialValue: "",
                    in: {
                      $cond: [
                        {
                          $eq: [
                            "$$this._id",
                            "$$f.followingId"
                          ]
                        },
                        "$$this.fullName",
                        "$$value"
                      ]
                    }
                  }
                },
                isFollowed: true
              }
            ]
          }
        }
      }
    }
  }
])

I am not a fan of the lookup and the relational schema you have done. I wonder if embedding the followings array in the user document might make more sense.

Best regards,
Pavel

Hi Pavel,

Thanks for your response. For the isFollowed and isFollowing, I need to check whether the logged in user has already followed or being followed by each person in the followers and followings arrays.

Hi @nirmamalen,

This sounds like this query will be complicated and insufficient. I would suggest refactoring the module to have people you follow or following embedded in user documents , if the list grows big offload it into another collection with a pointer:

https://www.mongodb.com/blog/post/building-with-patterns-the-outlier-pattern

Hope this helps, if not consider splitting this into several queries from the client side.

Best
Pavel