Как передать данные Dynami c во всех операторах MongoDB? - PullRequest
0 голосов
/ 18 апреля 2020

Цель -

У меня есть приложение чата, в котором у каждого пользователя есть список друзей, который хранится в коллекциях пользователей, и для каждого разговора с другом детали хранятся в коллекции чатов. В настоящее время я извлекаю список друзей из одного запроса (из коллекции «Пользователи») и сведения о чатах / chatId из другого (из коллекции «Чаты»), теперь я хочу получить список друзей по списку друзей с помощью одного запроса.

Обзор схемы пользователей и коллекции чатов -

//Users collection
Users = [
    //invidual users
    {
        username: "john_doe",
        manageFriends: {
            //friends-list
            friends: [
                // individual friend
                {
                    username: "jane_doe"
                },
                ...more_friends
            ]
        },
        ...other_fields,
    },
    {
        username: "jane_doe",
        manageFriends: {
            friends: [{ username: "john_doe" }, ...more_friends]
        },
        ...other_fields,
    },
    ...
]

//Chatrooms collection
Chatrooms = [
    //per conversation unique chatId along with participants details and messages
    {
        chatId: "abc_def",
        participants: ["john_doe", "jane_doe"], //username of two friends involved in conversation
        ...other_fields,
    }, {
        chatId: "abc_def",
        participants: ["john_doe", "someone_else"],
        ...other_fields,
    }
]


// query to fetch friends list(ignore pendingRequests stuffs)

        let users = await User.aggregate([
            {
                $match: { username }
            }, 
            {
                $project: {
                    "manageFriends": 1,
                    "username":1,
                    _id: 0
                }
            }, 
            {
                $unwind: {
                    path: "$manageFriends.friends",
                    preserveNullAndEmptyArrays: true
                }
            }, 
            {
                $lookup: {
                    "from": "chatrooms",
                    "pipeline" : [ 
                        { $match:  { participants: { $all : [username, "$manageFriends.friends.username"] }}},
                        { $project : {chatId : 1} }
                    ],
                    "as": "chatDetails"
                }
            },
            {
                $lookup:{
                    "from":"users",
                    "localField":"manageFriends.friends.username",
                    "foreignField":"username",
                    "as":"friendsRef"
                }
            },
            {
                $unwind: {
                    path: "$manageFriends.pendingFriendList",
                    preserveNullAndEmptyArrays: true
                }
            },
            {
                $project: {
                    "friends": {
                        $cond : ["$manageFriends.friends", {
                            "username":"$manageFriends.friends.username",
                            "name":"$manageFriends.friends.name",
                            "chatId": "$chatDetails.chatId",
                            "isOnline":  {$eq:[{$arrayElemAt: ["$friendsRef.status", 0 ]}, 'online']},
                            "lastSeen": {$arrayElemAt: ["$friendsRef.lastSeen", 0 ]},
                            "friendStatus":{
                                "isFriend":{$toBool:true},
                                "pendingStatus":null
                            }
                        }, '']
                    },
                    "username":1,
                    "pendingFriendList": {
                        $cond : ["$manageFriends.pendingFriendList", {
                            "username":"$manageFriends.pendingFriendList.username",
                            "name":"$manageFriends.pendingFriendList.name",
                            "friendStatus":{
                                "isFriend":{$toBool:false},
                                "pendingStatus": { "sentBy": "$manageFriends.pendingFriendList.sentBy"}
                            }
                        }, '']
                    },
                }
            },
            {
                $group: {
                    _id:"$username", 
                    "friends":{$addToSet: "$friends"},
                    "pendingFriendList":{$addToSet:"$pendingFriendList"}
                }
            },
            {
                $project: {
                    _id:0, 
                    "users":{$concatArrays:["$friends", "$pendingFriendList"]}
                }
            }    
        ]);

Довольно долго, но, наконец, вопрос - как передать имя пользователя друга в запросе ниже и получить только совпадающий chatId, потому что передача $ manageFriends.friends.username или $ username не возвращать результаты, но возвращать строки с жестким кодом?

            {
                $lookup: {
                    "from": "chatrooms",
                    "pipeline" : [ 
                        { $match:  { participants: { $all : [username, "$manageFriends.friends.username"] }}},
                        { $project : {chatId : 1} }
                    ],
                    "as": "chatDetails"
                }
            }

С уважением и счастливым кодированием, Принц

...