user14849955
user14849955

Reputation:

Query and Match from Two Database Collections (Mongoose/MongoDB)

I need help making a mongoose query that finds the requesting user's likes in the user collection, then searches for the user's likes in the posts collection. Hopefully, someone can tell me what I am doing wrong in my query or how I can do it better.

Users and Posts Collections:

const users = [
{
  _id: "1",
  likes: ["1", "2"]
},
{
  _id: "2",
  likes: ["3"]
}
]

const posts = [
{
  _id: "1",
  stuff: "stuff1"
},
{
  _id: "2",
  stuff: "stuff2"
},
{
  _id: "3",
  stuff: "stuff3"
}
]

Aggregate query:

router.post("/", authUser, async (req, res) => {
  User.aggregate([
    {
      $match: {
        _id: ObjectId(req.user._id), //user 1
      },
    },
    {
      $unwind: "$likes",
    },
    {
      $lookup: {
        from: "posts",
        let: { like: "$likes" },
        pipeline: [
          {
            $match: {
              $expr: {
                $eq: ["_id", "$$like"],
              },
            },
          },
        ],
        as: "matched_posts",
      },
    },
    {
      $unwind: "$matched_posts",
    },
  ]).then((d) => {
    console.log(d);
  });
});

Desired output:

const output = [
{
  _id: "1",
  stuff: "stuff1"
},
{
  _id: "2",
  stuff: "stuff2"
}
]

Upvotes: 1

Views: 78

Answers (1)

turivishal
turivishal

Reputation: 36154

  • $match your conditions
  • $lookup with posts collection, pass likes as localField and _id as foreignField
  • $unwind deconstruct likes array
  • $replaceRoot to replace likes object
router.post("/", authUser, async (req, res) => {
  User.aggregate([
    { $match: { _id: ObjectId(req.user._id) } },
    {
      $lookup: {
        from: "posts",
        localField: "likes",
        foreignField: "_id",
        as: "likes"
      }
    },
    { $unwind: "$likes" },
    { $replaceRoot: { newRoot: "$likes" } }
  ])
  .then((d) => {
    console.log(d);
  });
});

Playground

Upvotes: 0

Related Questions