skip to Main Content

I have notifications schema like this

user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User", //this may be null if user is not in system
  },
userEmail: {
    type: String,
    //required: [true, "User Email cannot be empty"],
  },
notifications: [
    {
        notificationTemplate: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "NotificationTemplate",
        required: [true, "Notification Template cannot be empty"],
      },
 ..]

I am trying to find user notifications with pagination and populate notificationTemplate but somehow it never populate notificationTemplate field. Each user can have multiple documents in Notifications.

here is my try

  const doc = await Notifications.aggregate([
    { $match: { user: mongoose.Types.ObjectId(req.params.userId) } },
    //{ $unwind: "$notifications" },
    { $match: { "notifications.protocols": { $in: ["webapp"] } } },
    {
      $lookup: {
        localField: "notificationTemplate",
        foreignField: "_id",
        from: "NotificationTemplate", // Replace with the actual collection name
        as: "notificationTemplate",
      },
    },
    { $sort: { "notifications.createdOn": -1 } }, // Sort by createdOn field in descending order
    { $skip: (page - 1) * parseInt(itemsPerPage) },
    { $limit: parseInt(itemsPerPage) },
    { $project: { notifications: 1 } },
    //{ $unwind: "$notifications" },
 ]);

Here is how i recieve data, note that notificationTemplate is always id

 [
   {
    attachment: [],
    protocols: [ 'email', 'webapp' ],
    isRead: false,
    isDeleted: false,
    createdOn: 2023-11-03T16:46:59.372Z,
    notificationTemplate: 65451f5277306d1d2c418cd5,
    url: '/session/654524e33e894e35ac4c00b9',
    by: 63a66a814e32a254204776e8,
    sentWeb: 2023-11-03T16:50:43.769Z,
    notificationParameters: { subject: 'Networking iDea' },
    sentEmail: 2023-11-03T16:50:45.766Z,
    _id: 654524e59c36fe07f08542c5
  }
]

2

Answers


  1. In $lookup, localField must be different from as field.

    Otherwise, it won’t work correctly.

    For example, notificationTemplete field is 65451f5277306d1d2c418cd5 but there is no data with _id like that in NotificationTemplete collection.

    result’s notificationTemplete field won’t be changed to Object and remaining in 65451f5277306d1d2c418cd5.

    In your query, ‘localField’ is ‘notificationTemplate’ and ‘as’ is also ‘notificationTemplate’.

    Change one and it’ll works correctly.

    For example

      $lookup: {
        localField: "notificationTemplate",
        foreignField: "_id",
        from: "NotificationTemplate", 
        as: "notificationTemplateInfo",
      },
    

    Then result will be

     [
       {
        attachment: [],
        protocols: [ 'email', 'webapp' ],
        isRead: false,
        isDeleted: false,
        createdOn: 2023-11-03T16:46:59.372Z,
        notificationTemplateInfo: 65451f5277306d1d2c418cd5,
        url: '/session/654524e33e894e35ac4c00b9',
        by: 63a66a814e32a254204776e8,
        sentWeb: 2023-11-03T16:50:43.769Z,
        notificationParameters: { subject: 'Networking iDea' },
        sentEmail: 2023-11-03T16:50:45.766Z,
        _id: 654524e59c36fe07f08542c5
      }
    ]
    

    I hope this answer can help you.

    Good luck.

    Login or Signup to reply.
  2. Your notificationTemplate is a property of the objects stored in the notifications array so you need access them in that way. Without seeing your schema this is a little like shooting in the dark but based on what you’ve shared your lookup should look like this:

        {
          $lookup: {
            localField: "notifications.notificationTemplate",
            foreignField: "_id",
            from: "NotificationTemplate", // Replace with the actual collection name
            as: "notificationTemplate",
          },
        },
    

    However, $lookup returns an array so that changes the shape of your documents. You will now have an array named notificationTemplate on the same level as the notifications array, not nested inside each notifications object.

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