Как получить пользователей обложки входящих сообщений и их последние сообщения в NodeJS с MongoDb - PullRequest
1 голос
/ 26 апреля 2019

Коллекция пользователей MongoDb


Думайте, что вы Пользователь 1 .На странице входящих я хочу получить последнее сообщение разговора.Я могу отправить последнее сообщение или получить последнее сообщение от пользователя.Последнее сообщение будет показано во входящих сообщениях следующим образом:

Результат запроса будет выглядеть следующим образом

[
  {
    "_id": "user2",
    "username": "user2",
    "lastMessage": "3"
  },
  {
    "_id": "user3",
    "username": "user3",
    "lastMessage": "2"
  }
]

Документ пользователя 1 на MongoDb

{
    "_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")
        }
    ]
}

Документ пользователя 2 на MongoDb

{
    "_id" : ObjectId("user2"),
    "username" : "user2",
    "inbox" : [ 
        {
            "from" : {
                "user" : {
                    "id" : ObjectId("user1")
                }
            },
            "message" : "3",
            "received_at" : ISODate("2019-04-29")
        }
    ]
}

Документ пользователя 3 на MongoDb

{
    "_id" : ObjectId("user3"),
    "username" : "user3",
    "inbox" : [ 
        {
            "from" : {
                "user" : {
                    "id" : ObjectId("user1")
                }
            },
            "message" : "4",
            "received_at" : ISODate("2019-04-30")
        }
    ]
}

Какой запрос я должен использовать для этой проблемы?

1 Ответ

1 голос
/ 26 апреля 2019

Вы можете использовать агрегацию ниже:

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], и оба должны быть рассмотреныкак тот же ключ группировки.

Для этого вы можете ввести массив participants, чтобы отфильтровать все сообщения, не принадлежащие user1, а затем удалить user1 из этого массива (используя $ filter ), чтобы вы могли группировать по второму пользователю.

Дело в том, что вы запускаете $ unwind , чтобы получить один документ на сообщение, а затем $ sort их, чтобы вы могли запустить $ group с $ first , чтобы получить самый последний

Mongo Playground

...