且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

$lookup 为子数组中的每个元素

更新时间:2023-02-18 13:56:19

您可以从 comments 集合和 $lookup with customers 得到 customer 名字,然后你就可以$group 评论和 $lookup 两次(使用 reviewscustomer).每次你知道这是一对一的关系时,你可以使用 $unwind$lookup 之后.试试:

You can start from comments collection and $lookup with customers to get customer name, then you can $group all comments by review and $lookup twice (with reviews and customer). Every time you know that it's a one-to-one relationship you can use $unwind after $lookup. Try:

db.comments.aggregate([
    {
        $lookup: {
            from: "customers",
            localField: "customerID",
            foreignField: "_id",
            as: "customer"
        }
    },
    {
        $unwind: "$customer"
    },
    {
        $project: {
            _id: 1,
            reviewID: 1,
            username: "$customer.username",
            message: 1
        }
    },
    {
        $group: {
            _id: "$reviewID",
            comments: { $push: { _id: "$_id", username: "$username", message: "$message" } }
        }
    },
    {
        $lookup: {
            from: "reviews",
            localField: "_id",
            foreignField: "_id",
            as: "review"
        }
    },
    {
        $unwind: "$review"
    },
    {
        $lookup: {
            from: "customers",
            localField: "review.customerID",
            foreignField: "_id",
            as: "customer"
        }
    },
    {
        $unwind: "$customer"
    },
    {
        $project: {
            _id: 1,
            message: "$review.message",
            username: "$customer.username",
            comments: 1
        }
    }
])

输出:

{ "_id" : 1, "comments" : [ { "_id" : 1, "username" : "jane", "message" : "my response" } ], "message" : "my message", "username" : "jack" }

如果您想从 reviews 开始并将其过滤为单个电影,则可以使用 $lookup 与自定义管道

If you want to start from reviews and filter it out to single movie you can then you can use $lookup with custom pipeline

db.reviews.aggregate([
    {
        $match: {
            movieId: 1,
        }
    },
    {
        $lookup: {
            from: "customers",
            localField: "customerID",
            foreignField: "_id",
            as: "customer"
        }
    },
    {
        $unwind: "$customer"
    },
    {
        $lookup: {
            from: "comments",
            let: { reviewId: "$_id" },
            pipeline: [
                {
                    $match: { $expr: { $eq: [ "$$reviewId", "$reviewID" ] } }
                },
                {
                    $lookup: {
                        from: "customers",
                        localField: "customerID",
                        foreignField: "_id",
                        as: "customer"
                    }
                },
                {
                    $unwind: "$customer"
                },
                {
                    $project: {
                        _id: 1,
                        message: 1,
                        username: "$customer.username"
                    }
                }
            ],
            as: "comments"
        }
    },
    {
        $project: {
            _id: 1,
            message: 1,
            username: "$customer.username",
            comments: 1
        }
    }
])

带来相同的输出