如何在mongoDB中聚合查找子数组文档,并投影结果?

时间:2019-12-21 07:27:37

标签: mongodb mongoose

我有2个收藏夹

  1. 帖子
  2. 用户

帖子集合包含包含{ userId, comment }对象以及其他信息的注释数组。

用户选择包含用户的信息。

我想返回完整的结果。

例如:

{
    "postId":"xvzeee",
    "post": "Good Morning",
    "likedBy":[ 
        12342234,
        23456534
    ]
    "comments": [
    {   
        "comment": "very good morning",
        "userName": "Max"
    },
    {
        "comment": "v. GM",
        "userName": "Suraj"
    }
    ]
}

我要达到上述结果的方法是

db.wall.aggregate([
    { $lookup: { from: 'profiles', localField: 'likedBy', foreignField: 'profileId', as: 'likedBy' } },
    { $lookup: { from: 'profiles', localField: 'comments.commentedBy', foreignField: 'profileId', as: 'commentedUser' } },
    {
        $project:{ 
            "likedBy.name": 1,
            "likedBy.profileId": 1,
            createdBy: 1,
            createdAt: 1,
            updatedAt: 1,
            comments : [{
                comment: "$comments.comment",
                user: "$commentedUser.name"
            }],
            "commentedUser.name" : 1
        }
    }
])

结果如下:

{
    "_id" : ObjectId("5dfdbb129f644213c413eb18"),
    "likedBy" : [
        {
            "profileId" : "96444206",
            "name" : "Vinay3"
        },
        {
            "profileId" : "400586806",
            "name" : "Dev"
        }
    ],
    "createdBy" : "96444206",
    "commentedUser" : [
        {
            "name" : "Vinay3"
        },
        {
            "name" : "Dev"
        }
    ],
         /*Facing problem in comment array*/
    "comments" : [
        {
            "comment" : [
                "Super-awesome",
                "FAB",
            ],
            "user" : [
                "Vinay3",
                "Dev"
            ]
        }
    ]
}

评论应如下所示:

[{
 ...
"comments" : [
        {
            "comments" : [
                { 
                   comment :"Super-awesome",
                   user: "Vinay3",
                   profileId: "11111..."
                },
                {
                   comment: "FAB",
                   user: "Dev",
                   profileId: "2222..."
                }
            ],
        }
    ]
}]

帖子收藏集如下:

[{
    "_id" : ObjectId("5dfdbb129f699913c413eb18"),
    "post":"Good Morning",
    "createdBy" : "96444206",
    "postId" : "D9644s5h8m",
    "likedBy" : [
        "96444206",
        "40058680"
    ],
    "comments" : [
        {
            "commentId" : "COM9644",
            "commentedBy" : "96444206",
            "comment" : "Super-awesome"
        },
        {
            "commentId" : "COM9644",
            "commentedBy" : "96444206",
            "comment" : "#FAB"
        },
        {
            "commentId" : "COM00587",
            "commentedBy" : "400586806",
            "comment" : "marvelous"
        }
    ],
    "createdAt" : ISODate("2019-12-21T11:56:26.944+05:30"),
    "updatedAt" : ISODate("2019-12-21T12:12:35.047+05:30"),
    "__v" : 0
}, {...}, {...}]

用户个人资料集合

[{
    "_id" : ObjectId("5dd4ff3abe53181160efa446"),
    "accountStatus" : "CONFIRMED",
    "profileId" : "400586806",
    "name" : "Dev",
    "email" : "dev@xyz.com",
    "createdAt" : ISODate("2019-11-20T14:24:18.692+05:30"),
    "updatedAt" : ISODate("2019-12-20T16:58:06.041+05:30"),
    "__v" : 0
}, {...}, {...} ]

如何实现这一目标,我们将不胜感激。

2 个答案:

答案 0 :(得分:0)

但是,我可以解决如下问题。

如果有比此更好的解决方案,将不胜感激。

db.wall.aggregate([
    { $unwind: '$comments'},
    { $lookup: { from: 'profiles', localField: 'comments.commentedBy', foreignField: 'profileId', as: 'comments.user' } },
    { $unwind: '$comments.user' },
    { 
        $group: {
            _id:'$_id',
            postId:  { $first: "$postId"},
            likedBy: { $first: "$likedBy"},
            createdBy: { $first: '$createdBy'},
            comments: { $push : '$comments' },
            createdAt: { $first: "$createdAt" },
            updatedAt: { $first: "$updatedAt" },
        }
    },{
        $project: { 
            _id:1,
            postId: 1,
            "likedBy.name": 1,
            "likedBy.profileId": 1,
            createdBy: 1,
            comments: { 
                $map : {
                    input: '$comments',
                    as: 'com',
                    in: {
                        commentId: "$$com.commentId",
                        comment: "$$com.comment",
                        name: "$$com.user.name"
                    }
                }
            },
            createdAt: 1,
            updatedAt: 1,
        }
    }
])

我想将isActive => true || false字段添加到注释对象。 现在的挑战是如何仅过滤isActive => true条评论?

答案 1 :(得分:0)

这是我的方法

db.posts.aggregate([
    {
        $unwind: '$likedBy',
    },
    {
        $unwind: '$comments',
    },
    {
        $lookup: {
            from: 'users',
            localField: 'likedBy',
            foreignField: 'profileId',
            as: 'likedByUser'
        },
    },
    {
        $unwind: '$likedByUser'
    },
    {
        $lookup: {
            from: 'users',
            localField: 'comments.commentedBy',
            foreignField: 'profileId',
            as: 'commentByUser'
        },
    },
    {
        $unwind: '$commentByUser'
    },
    {
        $group: {
            "_id": '$postId',
            "post": { $first: 'post'} ,
            comments: {
                $push: {
                    "commentId": "$comments.commentId",
                    "commentedBy": "$likedByUser.name",
                    "comment": "$comments.comment"
                }
            },
            likes: {
                 $push: {
                    "likedByName": "$likedByUser.name",
                    "likeById": "$likedBy"
                }
            }
        }
    },
    {
        $project: {
            "_id": 0,
            "postId":'$_id',
            "post": 1,
            "comments": 1,
            "likes": 1
        }
    }
])