Hỏi cách limit document trả về trong hàm $lookup hoặc $graphLookup mongodb?



  • Mình đang truy suất 1 bảng comment trong đó có comment_cha sẽ được lòng các comment_con vào thông qua _id nhưng mình không biết cách limit số lượng con. Mong mấy bạn giúp hoặc gốp ý cách nào tối ưu hơn.

    exports.loadComments = function (req, res) {
        var slug = req.query.slug;
        if(!slug) return res.json({error: "Không lấy được slug bài viết"});
        var trang = req.query.page ? req.query.page : 1;
        var limit = config.limit;
        var skip =  (trang - 1) * limit;
        var tempArray = [];
        commentsModel.aggregate([
            {$project: {_id: 1, user_ObjectId: 1, comment_ObjectId: 1, commentContent: 1, commentModify: 1, post_slug: 1, point: {$subtract: ['$commentUpVote','$commentDownVote']}}},
            {$match : { post_slug : slug, comment_ObjectId: null } },
            {$sort : { point : -1, commentModify: -1 } },
            {
                $lookup:
                  {
                    from: "users",
                    localField: "user_ObjectId",
                    foreignField: "_id",
                    as: "user"
                  }
             },
             {
                $graphLookup: { //Chổ này là nó truy xuất lòng nhau mà không biết phải thêm chữ gì vô cho nó limit lại đã thử thêm $limit nhưng lỗi
                    from: "comments",
                    startWith: "$_id",
                    connectFromField: "_id",
                    connectToField: "comment_ObjectId",
                    as: "Comments_child"
                 }
             },
             { $skip: skip },
             { $limit: 2 }
        ],  function (err, result) {
            if (err) {
                console.log(err);
                res.json({'error': 'Không kết nối được máy chủ! F5 thử lại'})
            } else {
                var data = ({page: parseInt(trang) + 1, comments: result})
                return res.json(data);
            }
        }).allowDiskUse(true);
    }
    
    //dữ liệu trã về
    {
        "page": 2,
        "comments": [
            {
                "_id": "5b24bc26e281911588e79b9a",
                "comment_ObjectId": null,
                "commentContent": "9",
                "post_slug": "0Pxzb9f",
                "user_ObjectId": "5b1f417ba5290e11d4c39f1f",
                "commentModify": "2018-06-16T07:28:38.442Z",
                "t": null,
                "point": 0,
                "user": [
                    {
                        "_id": "5b1f417ba5290e11d4c39f1f",
                        "quyen_hang": 3,
                        "ten_dang_nhap": "1633029573462982",
                        "mat_khau": "$2b$10$i5KY9I.C.mES4vtoRXri2exzKoy97L6jsop7LKm02ktRK/QyKVzRi",
                        "email": "[email protected]",
                        "anh_dai_dien": "images/avatar/1633029573462982.jpg",
                        "ten": "Kha Pham",
                        "mang_xa_hoi": {
                            "facebook": [
                                {
                                    "id": "1633029573462982"
                                }
                            ]
                        },
                        "__v": 0
                    }
                ],
                "Comments_child": [ // có cách nào để limit cái này theo ý mình không
                    {
                        "_id": "5b24bc1de281911588e79b94",
                        "commentUpVote": 0,
                        "commentDownVote": 0,
                        "comment_ObjectId": "5b24bc26e281911588e79b9a",
                        "commentContent": "3",
                        "commentStatus": 1,
                        "commentImage": {
                            "type": null,
                            "url": null,
                            "video": null
                        },
                        "post_slug": "0Pxzb9f",
                        "user_ObjectId": "5b1f417ba5290e11d4c39f1f",
                        "commentCreate": "2018-06-16T07:28:29.531Z",
                        "commentModify": "2018-06-16T07:28:29.531Z",
                        "__v": 0
                    },
                    {
                        "_id": "5b24bc1ce281911588e79b93",
                        "commentUpVote": 0,
                        "commentDownVote": 0,
                        "comment_ObjectId": "5b24bc26e281911588e79b9a",
                        "commentContent": "2",
                        "commentStatus": 1,
                        "commentImage": {
                            "type": null,
                            "url": null,
                            "video": null
                        },
                        "post_slug": "0Pxzb9f",
                        "user_ObjectId": "5b1f417ba5290e11d4c39f1f",
                        "commentCreate": "2018-06-16T07:28:28.447Z",
                        "commentModify": "2018-06-16T07:28:28.447Z",
                        "__v": 0
                    },
                    {
                        "_id": "5b24bc1be281911588e79b92",
                        "commentUpVote": 0,
                        "commentDownVote": 0,
                        "comment_ObjectId": "5b24bc26e281911588e79b9a",
                        "commentContent": "1",
                        "commentStatus": 1,
                        "commentImage": {
                            "type": null,
                            "url": null,
                            "video": null
                        },
                        "post_slug": "0Pxzb9f",
                        "user_ObjectId": "5b1f417ba5290e11d4c39f1f",
                        "commentCreate": "2018-06-16T07:28:27.461Z",
                        "commentModify": "2018-06-16T07:28:27.461Z",
                        "__v": 0
                    }
                ]
            },
            {
                "_id": "5b24bc25e281911588e79b99",
                "comment_ObjectId": null,
                "commentContent": "8",
                "post_slug": "0Pxzb9f",
                "user_ObjectId": "5b1f417ba5290e11d4c39f1f",
                "commentModify": "2018-06-16T07:28:37.442Z",
                "t": null,
                "point": 0,
                "user": [
                    {
                        "_id": "5b1f417ba5290e11d4c39f1f",
                        "quyen_hang": 3,
                        "ten_dang_nhap": "1633029573462982",
                        "mat_khau": "$2b$10$i5KY9I.C.mES4vtoRXri2exzKoy97L6jsop7LKm02ktRK/QyKVzRi",
                        "email": "[email protected]",
                        "anh_dai_dien": "images/avatar/1633029573462982.jpg",
                        "ten": "Kha Pham",
                        "mang_xa_hoi": {
                            "facebook": [
                                {
                                    "id": "1633029573462982"
                                }
                            ]
                        },
                        "__v": 0
                    }
                ],
                "Comments_child": []
            }
        ]
    }
    

    graphLookup document
    https://docs.mongodb.com/manual/reference/operator/aggregation/graphLookup/index.html#examples



  • Đã thử maxDepth là độ sâu của truy vấn lòng nên củng không hiệu quả do comment_cha có rất nhiều comment_con mà comment_con không là cha của ai cả.



  • Nếu mongo. Sao bạn không tách riêng từng câu query. Đừng join làm chi cả ~~. Với mình thấy join nhiều khó quản lý. Mà câu query cũng khó tái sử dụng. ý kiến cá nhân nha. =)).



  • Tách ra limit dễ. Dùng lại cũng dễ. =)). Vì kiểu gì collection kia bản chả lưu 1 cái field để relation.
    Ví dụ bài blog này nói về các thế mạnh, dở, và như hạch của mongo.: https://dzone.com/articles/mongodb-the-good-the-bad-and-the-ugly
    Thì mục join của nó nằm ở cái như hạch. H thì mình k rõ. Ví dụ bạn thích sử dụng join nhiếu -> MySQL, Postgres. Còn bạn muốn nhưng model nó thiết kế flexible như kiểu action và source_action design table của tụi trend bây h thì dùng mongo =))).



  • @Nguyen-Hien Tại muốn gộp chung 1 aggregate cho gọn haha. Vậy chắc phải làm cách bạn nói rồi chờ cho nó thực hiện xong 1 lookup rồi thực hiệp tiếp trong hàm callback của nó đúng không. Cám ơn bạn nhiều



  • @Nguyen-Hien mình thực hiện theo những bước sao ko biết có đúng ý bạn muốn nói vs mình không mà cảm giác truy vấn chậm hơn so với mình lấy tất cả comment con bằng aggregate

    • Lấy giữ liệu tất cả bình luận là cha

    • Dùng hàm map chạy danh sách cha để tìm con của nó

    • Khi tìm được con gán nó vào 1 mới thuộc cha tương ứng

    • Trả kết quả về client



  • @Kha-Pham Cái layout frontend có thể tách rời api k ?. Bạn thử tách làm 2 đi. 1 lấy cha. 1 lấy con theo id cha. =)).
    Còn per mình nghĩ là chạy ổn đi. Sau đó bạn maintain và scale tiếp. Với mình chửa benchmark mà. Nên vội gì kết luận.

    Tại vì mình cũng chưa thấy layout bên bạn. Có khi lại ko cần thiết get data về ngay lúc này sớm. Sau này cần thì load. 2 api tách kiểu kia thì restful cũng dễ mà đung k.
    /parents và /parents/parents:id/children



  • @Nguyen-Hien à. Mình hiểu rồi thank bạn


Log in to reply