skip to Main Content

I have this function:

const getNotificationsForLounge = async (lounge_id) => {
  try {
    const notifications = await Notification.aggregate([
      {
        $match: {
          "lounge_join_request.lounge": lounge_id,
          lounge_join_request: { $ne: null },
        },
      },
    ]);
    console.log("🚀 ~ notifications:", notifications);
    // Do something with the notifications
    return notifications;
  } catch (error) {
    console.log("🚀 ~ error:", error);
    // Handle the error
  }
};

I feed it a lounge_id and it searchs the notifications where notification.lounge_join_request.lounge is equal that lounge_id.

I wrote a second function that pulls a random notification and gets its lounge_join_request.lounge_id and then feeds that lounge_id to the first function.

const getNotificationWithRandomLoungeJoinRequest = async () => {
  try {
    const notification = await Notification.aggregate([
      // Match notifications with lounge join requests
      {
        $match: {
          category: "LOUNGE_JOIN_REQUEST",
          lounge_join_request: { $ne: null },
        },
      },
      // Select a random notification using $sample
      { $sample: { size: 1 } },
      {
        $lookup: {
          from: "lounge_join_requests",
          localField: "lounge_join_request",
          foreignField: "_id",
          as: "lounge_join_request",
        },
      },
      // Project the lounge ID
      { $project: { _id: 0, lounge_id: "$lounge_join_request.lounge" } },
    ]);
    const lounge_id = notification[0].lounge_id[0];
    // Logs a lounge id
    // 🚀 ~ file: loungeServices.js:663 ~ getNotificationWithRandomLoungeJoinRequest ~ lounge_id: 63ef344xxxxb4943355
    // Which means there exists a notification
    // Where notification.lounge_join_request.lounge equals this lounge_id
    console.log(
      "🚀 ~ file: loungeServices.js:663 ~ getNotificationWithRandomLoungeJoinRequest ~ lounge_id:",
      lounge_id
    );

    // But, when I feed that lounge_id into this function
    // Which searchs notifications where
    // notification.lounge_join_request.lounge equals this lounge_id
    // It logs an empty array
    return await getNotificationsForLounge(lounge_id);
  } catch (error) {
    console.log("🚀 ~ error:", error);
  }
};

Since, I pulled that lounge_id from an existing notification. The first function should at least return an array containing that notification.

But, it doesn’t, it always returns an empty array. Focus on this part:

 const lounge_id = notification[0].lounge_id[0];
    // Logs a lounge id
    // 🚀 ~ file: loungeServices.js:663 ~ getNotificationWithRandomLoungeJoinRequest ~ lounge_id: 63ef344xxxxb4943355
    // Which means there exists a notification
    // Where notification.lounge_join_request.lounge equals this lounge_id
    console.log(
      "🚀 ~ file: loungeServices.js:663 ~ getNotificationWithRandomLoungeJoinRequest ~ lounge_id:",
      lounge_id
    );

    // But, when I feed that lounge_id into this function
    // Which searchs notifications where
    // notification.lounge_join_request.lounge equals this lounge_id
    // It logs an empty array
    return await getNotificationsForLounge(lounge_id);

Any idea why?


These are the relevant models:

Notification.js

const NotificationSchema = new Schema({
  lounge_join_request: {
    type: Schema.Types.ObjectId,
    ref: "lounge_join_requests",
    default: null,
  },
});

module.exports = Notification = mongoose.model(
  "notification",
  NotificationSchema
);

LoungeJoinRequest.js

const LoungeJoinRequestSchema = new Schema({
  lounge: {
    type: Schema.Types.ObjectId,
    ref: "lounge",
    required: true,
  },
});

module.exports = LoungeJoinRequest = mongoose.model(
  "lounge_join_requests",
  LoungeJoinRequestSchema
);

Lounge.js

const LoungeSchema = new Schema(
  {
    name: {
      type: String,
    },
  }
);

module.exports = Channel = mongoose.model("lounge", LoungeSchema);

2

Answers


  1. In your schema the lounge_join_request field contains an ObjectId, not an object, so there is no lounge_join_request.lounge field to match against.

    If lounge_id contains a match for the _id of the lounge join request document, you can match with

     {
         $match: {
            lounge_join_request: lounge_id,
            lounge_join_request: { $ne: null },
         },
     }
    
    Login or Signup to reply.
  2. The problem you have mentioned, I think problem is not there. Because first aggregation does return a result if you have lounge attribute set in lounge_join_requests collection. You can check it in here Mongo Playground Snippet

    I think problem is in your getNotificationsForLounge method. As you are trying to find notification by lounge_id and that lounge_id is for lounge collection. notification collection has no relation with lounge collection. So, finding by lounge_id from lounge collection will do no help.

    If you need to do so then you can try getNotificationsForLounge like this –

    const getNotificationsForLounge = async (lounge_id) => {
      try {
        const notifications = await Notification.aggregate([
          {
            $lookup: {
              from: "lounge_join_requests",
              localField: "lounge_join_request",
              foreignField: "_id",
              as: "lounge_join_request",
            },
          },
          {
            $match: {
              "lounge_join_request.lounge": lounge_id,
              "lounge_join_request": { $ne: null },
            },
          }
        ]);
        console.log("🚀 ~ notifications:", notifications);
        // Do something with the notifications
        return notifications;
      } catch (error) {
        console.log("🚀 ~ error:", error);
        // Handle the error
      }
    };
    

    Hopefully this work. Let me know in the comment.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search