Bạn đang mắc sai lầm ngay từ đầu quy trình tổng hợp của mình
$project: {
"tasks" : 1
}
do đó bạn mất tất cả dữ liệu của mình. Vì vậy, trước hết bạn cần đặt trước khi thực hiện:
$project: {
tasks: 1,
doc: {
title: "$title",
order: "$order",
description: "$description",
status: "$status"
}
}
Sau đó, thực hiện $unwind
của bạn như bạn làm trong câu hỏi của mình:
{$unwind: "$tasks"}, {$unwind: "$tasks.subTasks"}
Sau đó thực hiện việc phân loại. Bạn cần thực hiện sắp xếp bằng các khóa ghép, nếu không thì sắp xếp theo tasks.subTasks.order
sẽ không giữ ngay sau khi bạn sắp xếp theo tasks.order
. Vì vậy:
{$sort: {"tasks.order": -1, "tasks.subTasks.order": 1}}
Và sau đó là phần khó. Bạn cần $group
trả lại kết quả và bước đầu tiên là $push
quay lại subTasks
, nhưng trước hết, một lần nữa, bạn cần duy trì các thuộc tính nhiệm vụ:
$project: {
doc: 1,
task_id: "$tasks._id",
tasks_doc: {
title: "$tasks.title",
description: "$tasks.description",
order: "$tasks.order",
status: "$tasks.status"
},
subTasks: "$tasks.subTasks"
}
... thu thập subTasks
:
$group: {
_id: {
_id: "$_id",
task_id: "$task_id",
doc: "$doc",
task_doc: "$tasks_doc"
},
subTasks: {
$push: "$subTasks"
}
}
Và tương tự đối với các tác vụ tasks
. Hãy chú ý rằng trong $group
ing bạn cũng cần chiếu lại task_doc
thuộc tính:
$group: {
_id: {
_id: "$_id._id",
doc: "$_id.doc"
},
tasks: {
$push: {
_id: "$_id.task_id",
title: "$_id.task_doc.title",
description: "$_id.task_doc.description",
order: "$_id.task_doc.order",
status: "$_id.task_doc.status"
subTasks: "$subTasks"
}
}
}
Và sau đó chiếu lại doc
gốc thuộc tính:
$project: {
_id: "$_id._id",
title: "$_id.doc.title",
description: "$_id.doc.description",
order: "$_id.doc.order",
status: "$_id.doc.status",
tasks: 1
}
Về cơ bản là nó. Đây là toàn bộ quy trình tổng hợp thô, vì vậy bạn có thể kiểm tra và xem liệu bạn có nhận được kết quả mong muốn hay không:
[
{$match: {_id: ObjectId("554a13d4b692088a38f01f3b")}},
{$project: {tasks: 1, doc: {title: "$title", order: "$order", description: "$description", status: "$status"}}},
{$unwind: "$tasks"},
{$unwind: "$tasks.subTasks"},
{$sort: {"tasks.order": -1, "tasks.subTasks.order": 1}},
{$project: {doc: 1, task_id: "$tasks._id", tasks_doc: {title: "$tasks.title", description: "$tasks.description", order: "$tasks.order", status: "$tasks.status"}, subTasks: "$tasks.subTasks"}},
{$group: {_id: {_id: "$_id", task_id: "$task_id", doc: "$doc", task_doc: "$tasks_doc"}, subTasks: {$push: "$subTasks"}}},
{$group: {_id: {_id: "$_id._id", doc: "$_id.doc"}, tasks: {$push: {_id: "$_id.task_id", title: "$_id.task_doc.title", description: "$_id.task_doc.description", order: "$_id.task_doc.order", status: "$_id.task_doc.status", subTasks: "$subTasks"}}}},
{$project: {_id: "$_id._id", title: "$_id.doc.title", description: "$_id.doc.description", order: "$_id.doc.order", status: "$_id.doc.status", tasks: 1}}
]
CẬP NHẬT
Nếu một trường mảng trống hoặc không tồn tại (null
) $unwind
thao tác trên trường đó sẽ trả về kết quả trống
. Giải pháp cho tình huống này ban đầu là thiết lập null
/ trường trống thành một số zero
giá trị, ví dụ:"<empty-array>"
. Lưu ý rằng bạn phải thực hiện $project
này ion cho mỗi mảng, trước $unwind
của nó .
Hãy xem câu trả lời này
về cách sử dụng $ifNull
nhà điều hành. Ngoài ra, hãy xem $size
toán tử tại đây
.
Sau khi xử lý phần này, bạn cần phải $group
trả lại kết quả và có thể đạt được điều này bằng cách sử dụng $cond
nhà điều hành
, để kiểm tra lại "<empty-array>"
giá trị