Вы можете начать с comments
коллекции и $ lookup с customers
, чтобы получить customer
имя, затем вы можете $ group все комментарии по обзору и $ lookup дважды (с reviews
и customer
).Каждый раз, когда вы знаете, что это отношение один-к-одному, вы можете использовать $ unwind после $ lookup .Попробуйте:
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
и отфильтровать его для одного фильма, вы можете использовать $поиск с пользовательским конвейером
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
}
}
])
Выводит тот же вывод