Mike K
Mike K

Reputation: 6491

Mongoose aggregation query return more than one record when it should return only one

I have the following query, it is supposed to pull out the most recent message sent from all users to a single user:

    await Conversation.aggregate(
      [
        // Matching pipeline, similar to find
        {
          $match: {
            recipient: mongoose.Types.ObjectId(id)
          }
        },
        // Sorting pipeline
        {
          $sort: {
            date: -1
          }
        },
        // Grouping pipeline
        {
          $group: {
            _id: "$_id",
            sender: {
              $first: "$sender"
            },
            text: {
              $first: "$text"
            },
            date: {
              $first: "$date"
            },
            unread: {
              $first: "$unread"
            }
          }
        },
        {
          $lookup: {
            from: "users",
            localField: "sender",
            foreignField: "_id",
            as: "sender"
          }
        },
        { $unwind: { path: "$sender" } },
        // Project pipeline, similar to select
        {
          $project: {
            sender: 1,
            _id: 1,
            text: 1,
            date: 1,
            unread: 1
          }
        }
      ],
      function(err, messages) {
        if (err) {
          console.log("err with agg query", err);
        } else {
          console.log("latestMessages", messages);
        }
      }
    );

The problem is that it returns more than one record. It returns:

[
  {
    _id: 5d9b51eed6606f12f5434d46,
    sender: {
      _id: 5d9b5142d6606f12f5434d41,
      email: null,
      numberOfPosts: 0,
      date: 2019-10-07T14:52:50.467Z,
      __v: 0
    },
    text: 'Ayyy',
    date: 2019-10-07T14:55:42.141Z,
    unread: false
  },
  {
    _id: 5d9b5178d6606f12f5434d43,
    sender: {
      _id: 5d9b5142d6606f12f5434d41,
      email: null,
      numberOfPosts: 0,
      date: 2019-10-07T14:52:50.467Z,
      __v: 0
    },
    text: 'hey!',
    date: 2019-10-07T14:53:44.073Z,
    unread: false
  }
]

When it should be returning just the first element where sender is 5d9b5142d6606f12f5434d41, the first, latest object.

What am I doing wrong here?

Upvotes: 0

Views: 235

Answers (1)

Rahul kumar
Rahul kumar

Reputation: 116

Change the qroup pipeline just like

You need to group by on sender not on unique _id

{
          $group: {
            _id: "$sender",
            sender: {
              $first: "$sender"
            },
            messageId: {
              $first: "$_id"
            },
            text: {
              $first: "$text"
            },
            date: {
              $first: "$date"
            },
            unread: {
              $first: "$unread"
            }
          }
        }

And change in $project

$project: {
            sender: 1,
            _id: "$messageId",
            text: 1,
            date: 1,
            unread: 1
          }

Upvotes: 1

Related Questions