MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

MongoDb Pipeline Aggregation sắp xếp các tài liệu phụ

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ị




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Truy vấn các tài liệu có trường con nội bộ của một giá trị nhất định

  2. Bắt đầu với Cơ sở dữ liệu không quan hệ bằng Mongodb 🍃

  3. Mongoose Query để lọc một mảng và điền nội dung liên quan

  4. Lược đồ tự tham chiếu Mongoose không tạo ObjectId cho tất cả các tài liệu con

  5. Cách sao chép cơ sở dữ liệu Mongodb với Mongoose