Node.js 如何获取收件箱';s覆盖率';使用MongoDb的NodeJS中的s用户及其最后一条消息 MongoDb用户集合

Node.js 如何获取收件箱';s覆盖率';使用MongoDb的NodeJS中的s用户及其最后一条消息 MongoDb用户集合,node.js,mongodb,mongoose,aggregation-framework,Node.js,Mongodb,Mongoose,Aggregation Framework,认为您是用户1。在收件箱页面中,我想获取对话的最后一条消息。我可以发送最后一条消息,也可以从用户处接收最后一条消息。最后一条消息将显示在收件箱中,如下所示: 查询结果应该是这样的 [ { "_id": "user2", "username": "user2", "lastMessage": "3" }, { "_id": "user3", "username": "user3", "lastMessage": "2" } ] Mo

认为您是用户1。在收件箱页面中,我想获取对话的最后一条消息。我可以发送最后一条消息,也可以从用户处接收最后一条消息。最后一条消息将显示在收件箱中,如下所示:

查询结果应该是这样的

[
  {
    "_id": "user2",
    "username": "user2",
    "lastMessage": "3"
  },
  {
    "_id": "user3",
    "username": "user3",
    "lastMessage": "2"
  }
]
MongoDb上的用户1文档

{
    "_id" : ObjectId("user1"),
    "username" : "user1",
    "inbox" : [ 
        {
            "from" : {
                "user" : {
                    "id" : ObjectId("user2")
                }
            },
            "message" : "1",
            "received_at" : ISODate("2019-04-27")
        },
        {
            "from" : {
                "user" : {
                    "id" : ObjectId("user3")
                }
            },
            "message" : "2",
            "received_at" : ISODate("2019-05-1")
        }
    ]
}
{
    "_id" : ObjectId("user2"),
    "username" : "user2",
    "inbox" : [ 
        {
            "from" : {
                "user" : {
                    "id" : ObjectId("user1")
                }
            },
            "message" : "3",
            "received_at" : ISODate("2019-04-29")
        }
    ]
}
{
    "_id" : ObjectId("user3"),
    "username" : "user3",
    "inbox" : [ 
        {
            "from" : {
                "user" : {
                    "id" : ObjectId("user1")
                }
            },
            "message" : "4",
            "received_at" : ISODate("2019-04-30")
        }
    ]
}
MongoDb上的用户2文档

{
    "_id" : ObjectId("user1"),
    "username" : "user1",
    "inbox" : [ 
        {
            "from" : {
                "user" : {
                    "id" : ObjectId("user2")
                }
            },
            "message" : "1",
            "received_at" : ISODate("2019-04-27")
        },
        {
            "from" : {
                "user" : {
                    "id" : ObjectId("user3")
                }
            },
            "message" : "2",
            "received_at" : ISODate("2019-05-1")
        }
    ]
}
{
    "_id" : ObjectId("user2"),
    "username" : "user2",
    "inbox" : [ 
        {
            "from" : {
                "user" : {
                    "id" : ObjectId("user1")
                }
            },
            "message" : "3",
            "received_at" : ISODate("2019-04-29")
        }
    ]
}
{
    "_id" : ObjectId("user3"),
    "username" : "user3",
    "inbox" : [ 
        {
            "from" : {
                "user" : {
                    "id" : ObjectId("user1")
                }
            },
            "message" : "4",
            "received_at" : ISODate("2019-04-30")
        }
    ]
}
MongoDb上的用户3文档

{
    "_id" : ObjectId("user1"),
    "username" : "user1",
    "inbox" : [ 
        {
            "from" : {
                "user" : {
                    "id" : ObjectId("user2")
                }
            },
            "message" : "1",
            "received_at" : ISODate("2019-04-27")
        },
        {
            "from" : {
                "user" : {
                    "id" : ObjectId("user3")
                }
            },
            "message" : "2",
            "received_at" : ISODate("2019-05-1")
        }
    ]
}
{
    "_id" : ObjectId("user2"),
    "username" : "user2",
    "inbox" : [ 
        {
            "from" : {
                "user" : {
                    "id" : ObjectId("user1")
                }
            },
            "message" : "3",
            "received_at" : ISODate("2019-04-29")
        }
    ]
}
{
    "_id" : ObjectId("user3"),
    "username" : "user3",
    "inbox" : [ 
        {
            "from" : {
                "user" : {
                    "id" : ObjectId("user1")
                }
            },
            "message" : "4",
            "received_at" : ISODate("2019-04-30")
        }
    ]
}


我必须使用什么查询来解决此问题?

您可以使用以下聚合:

db.col.aggregate([
    {
        $unwind: "$inbox"
    },
    {
        $addFields: {
            participants: [ "$_id", "$inbox.from.user.id" ]
        }
    },
    {
        $match: { participants: "user1" }
    },
    {
        $addFields: {
            participants: {
                $filter: {
                    input: "$participants",
                    cond: {
                        $ne: [ "$$this", "user1" ]
                    }
                }
            }
        }
    },
    {
        $unwind: "$participants"
    },
    {
        $sort: { "inbox.received_at": -1 }
    },
    {
        $group: {
            _id: "$participants",
            lastMessage: { $first: "$inbox.message" }
        }
    }
])
这里的挑战是,您需要分析可能包含例如[user1,user2]或[user2,user1]的数组,并且这两个数组都应被视为相同的分组键

为此,您可以引入
参与者
数组,以筛选出不属于
user1
的所有消息,然后从该数组中删除
user1
(使用),以便您可以按第二个用户分组

关键是,您可以运行以获取每条消息的单个文档,然后再获取它们,这样您就可以运行以获取最新的文档


谢谢你的回答。但是,有一个问题。因为,最后的消息必须是3和2。你的答案是3和4。遗漏的是“User1”在他们的对话中向“User3”发送了最后一条消息。@erefCanMuştu我一定错过了,抱歉,修改了我的答案,Mongo Playground非常感谢。你回答这个问题救了我的命@米克尔很抱歉再次评论你,但需要你再帮一个忙。有没有办法在结果中也获取用户名?我编辑了我的问题“如何才能得到结果”。我已经试过了,但是我在MongoDb不专业,所以我不能。好吧,你可以添加
{$first:$username}
,但是如果最后一条消息存储在
user1
id下,这将失败。两种方法:1。修改您的数据模型,并将
username
嵌入到每条消息中。2.使用$in运算符运行第二次查询,以按id获取用户名