我需要帮助聚合 mongoDb 聊天应用程序以接收来自每个相关聊天的最新消息

问题描述 投票:0回答:1

我正在尝试使用 React.js 和 Node.js/Express.js + MongoDB/Mongoose 制作一个聊天应用程序

我没有任何对话/聊天表,因为用户只有一个对话,所以我尝试通过聚合获取与每个用户相关的最新消息,唯一的问题是,它不返回最新消息它会针对每个请求返回一条随机记录。

这是我的消息架构

mongoose.Schema(
    {
        sender: {
            type: mongoose.Schema.Types.ObjectId,
            required: true,
            ref: "User",
        },
        receiver: {
            type: mongoose.Schema.Types.ObjectId,
            required: true,
            ref: "User",
        },
        text: {
            type: String,
            required: true,
        },
    },
)

我添加了 3 个名为 a、b、c 的用户进行测试

我添加了一些测试消息,如下所示:

[
  {
    _id: new ObjectId("6593533fcb45be67f96ad506"),
    sender: new ObjectId("659010d3df83767d3ccf7ef8"),
    receiver: new ObjectId("6591d954aeb1253a9a00111b"),
    text: 'Message from a to b',
    type: 'message',
    isForwarding: false,
    isEdited: false,
    status: 'unread',
    createdAt: 2024-01-02T00:05:19.734Z,
    updatedAt: 2024-01-02T00:05:19.734Z,
    __v: 0
  },
  {
    _id: new ObjectId("6593533fcb45be67f96ad507"),
    sender: new ObjectId("659010d3df83767d3ccf7ef8"),
    receiver: new ObjectId("65934563c5cc0035755d1bcc"),
    text: 'Message from a to c',
    type: 'message',
    isForwarding: false,
    isEdited: false,
    status: 'unread',
    createdAt: 2024-01-02T00:05:19.734Z,
    updatedAt: 2024-01-02T00:05:19.734Z,
    __v: 0
  },
  {
    _id: new ObjectId("6593533fcb45be67f96ad50a"),
    sender: new ObjectId("6591d954aeb1253a9a00111b"),
    receiver: new ObjectId("65934563c5cc0035755d1bcc"),
    text: 'Message from b to c',
    type: 'message',
    isForwarding: false,
    isEdited: false,
    status: 'unread',
    createdAt: 2024-01-02T00:05:19.735Z,
    updatedAt: 2024-01-02T00:05:19.735Z,
    __v: 0
  },
  {
    _id: new ObjectId("6593533fcb45be67f96ad50b"),
    sender: new ObjectId("65934563c5cc0035755d1bcc"),
    receiver: new ObjectId("6591d954aeb1253a9a00111b"),
    text: 'Message from c to b',
    type: 'message',
    isForwarding: false,
    isEdited: false,
    status: 'unread',
    createdAt: 2024-01-02T00:05:19.736Z,
    updatedAt: 2024-01-02T00:05:19.736Z,
    __v: 0
  },
  {
    _id: new ObjectId("6593533fcb45be67f96ad509"),
    sender: new ObjectId("65934563c5cc0035755d1bcc"),
    receiver: new ObjectId("659010d3df83767d3ccf7ef8"),
    text: 'Message from c to a',
    type: 'message',
    isForwarding: false,
    isEdited: false,
    status: 'unread',
    createdAt: 2024-01-02T00:05:19.735Z,
    updatedAt: 2024-01-02T00:05:19.735Z,
    __v: 0
  },
  {
    _id: new ObjectId("6593533fcb45be67f96ad508"),
    sender: new ObjectId("6591d954aeb1253a9a00111b"),
    receiver: new ObjectId("659010d3df83767d3ccf7ef8"),
    text: 'Message from b to a',
    type: 'message',
    isForwarding: false,
    isEdited: false,
    status: 'unread',
    createdAt: 2024-01-02T00:05:19.735Z,
    updatedAt: 2024-01-02T00:05:19.735Z,
    __v: 0
  },
  {
    _id: new ObjectId("659417678ea29bb72b66713e"),
    sender: new ObjectId("659010d3df83767d3ccf7ef8"),
    receiver: new ObjectId("6591d954aeb1253a9a00111b"),
    text: 'Last message from a to b',
    type: 'message',
    isForwarding: false,
    isEdited: false,
    status: 'unread',
    createdAt: 2024-01-02T14:02:15.773Z,
    updatedAt: 2024-01-02T14:02:15.773Z,
    __v: 0
  },
  {
    _id: new ObjectId("659417678ea29bb72b66713f"),
    sender: new ObjectId("659010d3df83767d3ccf7ef8"),
    receiver: new ObjectId("65934563c5cc0035755d1bcc"),
    text: 'Last message from a to c',
    type: 'message',
    isForwarding: false,
    isEdited: false,
    status: 'unread',
    createdAt: 2024-01-02T14:02:15.773Z,
    updatedAt: 2024-01-02T14:02:15.773Z,
    __v: 0
  }
]

这就是我尝试过的代码:


const Chats = await Message.aggregate([
    {
        $sort: {
            createdAt: -1,
        },
    },
    {
        $project: {
            receiver: 1,
            sender: 1,
            text: 1,
            timeStamp: 1,
            messageFrom: ["$sender", "$receiver"],
        },
    },
    {
        $unwind: "$messageFrom",
    },
    {
        $sort: {
            messageFrom: 1,
        },
    },
    {
        $group: {
            _id: "$_id",
            messageFrom: {
                $push: "$messageFrom",
            },
            sender: {
                $first: "$sender",
            },
            receiver: {
                $first: "$receiver",
            },
            text: {
                $first: "$text",
            },
        },
    },
    {
        $group: {
            _id: "$messageFrom",
            sender: {
                $first: "$sender",
            },
            receiver: {
                $first: "$receiver",
            },
            text: {
                $first: "$text",
            },
        },
    },
])

每次我发出新请求时,它都会返回一些意想不到的随机内容。

这就是我想要的回报:

[
  {
    _id: new ObjectId("659417678ea29bb72b667144"),
    sender: new ObjectId("659010d3df83767d3ccf7ef8"),
    receiver: new ObjectId("6591d954aeb1253a9a00111b"),
    text: 'Last message from a to b',
    type: 'message',
    isForwarding: false,
    isEdited: false,
    status: 'unread',
    createdAt: 2024-01-02T14:02:15.975Z,
    updatedAt: 2024-01-02T14:02:15.975Z,
    __v: 0
  },
  {
    _id: new ObjectId("659417678ea29bb72b66713f"),
    sender: new ObjectId("659010d3df83767d3ccf7ef8"),
    receiver: new ObjectId("65934563c5cc0035755d1bcc"),
    text: 'Last message from a to c',
    type: 'message',
    isForwarding: false,
    isEdited: false,
    status: 'unread',
    createdAt: 2024-01-02T14:02:15.773Z,
    updatedAt: 2024-01-02T14:02:15.773Z,
    __v: 0
  }
]
node.js mongodb express aggregate aggregation
1个回答
0
投票

也许这个:

db.collection.aggregate([
   {
      $group: {
         _id: { sender: "$sender", receiver: "$receiver" },
         messages: {
            $top: {
               sortBy: { createdAt: -1 },
               output: "$$ROOT"
            }
         }
      }
   },
   { $replaceWith: "$messages" },
])

$top
是在 MongoDB 5.2 版本中引入的。如果您运行旧版本,请尝试以下操作:

db.collection.aggregate([
   { $sort: { createdAt: -1 } },
   {
      $group: {
         _id: { sender: "$sender", receiver: "$receiver" },
         messages: { $first: "$$ROOT" }
      }
   },
   { $replaceWith: "$messages" },
])
© www.soinside.com 2019 - 2024. All rights reserved.