如何在 MongoDB 的 $lookup 中添加看不见的消息计数

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

我正在构建一个简单的聊天应用程序,它需要读取看不见的消息并在加载聊天参与者列表时将其发送回 UI。我没能这样做。

所以我有一个

user
架构,看起来像:

User {
  _id: ObjectId("12321hj32g1h3g21"),
  name:"Sam Smith",
  avatar:"http://somewebsite.com/dshauhu321",
  inbox: [
    { participant: ObjectId("1xxxxxxx"), added_at:"02/20/2021"}  // participant is also a user
    { participant: ObjectId("2xxxxxxx"), added_at:"04/03/2022"}
  ]
}

然后我有一个

message
系列看起来像:

Message {
  from: ObjectId("12321hj32g1h3g21"),
  to: ObjectId("1xxxxxxx"),
  msg_type: "TEXT",
  file_url: null,
  text: "Hello world",
  seen: false,
  time_seen: null
}

我能够使用

participants
运算符填充我的
$lookup
,我所拥有的是:

{
  _id: ObjectId("12321hj32g1h3g21"),
  name:"Sam Smith",
  avatar:"http://somewebsite.com/dshauhu321",
  inbox: [
    { 
       participant: {
           _id: ObjectId("1xxxxxxx"),
           name: "Joe Doe",
           avatar: "http://somewebsite.com/dgshagxjastyudsa",
           added_at: "02/20/2021"
       }
    },
    { 
       participant: {
           _id: ObjectId("2xxxxxxx"),
           name: "Emily Clark",
           avatar: "http://somewebsite.com/dsadsa",
           added_at: "04/03/2022"
       }
    },
  ]
}

现在我需要在每个参与者中多一个字段,我们称之为

"totalUnreadMessages"
。我需要在
messages
集合中查找,并根据“发件人”和“收件人”字段进行搜索,以获取用户与每个参与者之间的所有未读消息,并将其填充到每个参与者对象中。问题:我该怎么做? (我只需要一个总数,而不是实际的消息)

谢谢

javascript node.js database mongodb nosql
1个回答
0
投票

您要解决的问题可以通过使用 MongoDB 的聚合框架来解决,具体来说,您将需要使用 $lookup、$unwind 和 $group 操作。您可以这样做:

db.users.aggregate([
    // You already have the $lookup for the participant, let's keep it as it is
    {
        $lookup: {
            from: 'users',
            localField: 'inbox.participant',
            foreignField: '_id',
            as: 'inbox.participant'
        }
    },
    {
        $unwind: {
            path: '$inbox',
            preserveNullAndEmptyArrays: true
        }
    },
    {
        $unwind: {
            path: '$inbox.participant',
            preserveNullAndEmptyArrays: true
        }
    },
    // The next step would be to lookup messages and filter only the unread ones
    {
        $lookup: {
            from: 'messages',
            let: { participantId: '$inbox.participant._id', userId: '$_id' },
            pipeline: [
                {
                    $match: {
                        $expr: {
                            $and: [
                                { $eq: ['$to', '$$userId'] },
                                { $eq: ['$from', '$$participantId'] },
                                { $eq: ['$seen', false] }
                            ]
                        }
                    }
                }
            ],
            as: 'inbox.participant.unreadMessages'
        }
    },
    // Then, we can group them back and calculate the total unread messages
    {
        $group: {
            _id: '$_id',
            name: { $first: '$name' },
            avatar: { $first: '$avatar' },
            inbox: {
                $push: {
                    participant: '$inbox.participant._id',
                    name: '$inbox.participant.name',
                    avatar: '$inbox.participant.avatar',
                    added_at: '$inbox.added_at',
                    totalUnreadMessages: { $size: '$inbox.participant.unreadMessages' }
                }
            }
        }
    }
])

这将返回您想要的数据:用户详细信息、参与者详细信息以及每个用户和参与者之间的未读消息总数。

请注意,根据您的 MongoDB 版本,它可能不支持上面使用的某些功能。您可能需要相应地调整查询。

© www.soinside.com 2019 - 2024. All rights reserved.