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

mongodb:truy vấn vài hàng đầu tiên trong đó tổng của cột cụ thể lớn hơn hoặc bằng C

Truy vấn

Nó có thể được thực hiện bằng cách sử dụng khung tổng hợp . Xem xét quy trình tổng hợp tiếp theo

db.collectionName.aggregate([
  {
    $group: 
      { 
        "_id": null, 
        "ds": { $push: "$$ROOT" }, 
        "cs": { $push: "$c" } 
      } 
  }, /* (1) */
  { $unwind: "$ds" }, /* (2) */
  { 
    $project: 
      { 
        "_id": "$ds._id", 
        "c": "$ds.c", 
        "cs": { $slice: [ "$cs", "$ds._id" ] } 
      } 
  }, /* (3):  */
  { $unwind: "$cs" },  /* (4) */
  { 
    $group: 
      { 
        "_id": "$_id", 
        "c": { $first: "$c" }, 
        "csum": { $sum: "$cs" } 
      } 
  }, /* (5) */
  { 
    $group: 
      { 
        "_id": null, 
        "ds": { $push: "$$ROOT" }, 
        "gteC": 
          { 
            $push: 
              { 
                $cond: 
                  { 
                    if: { "$gte": [ "$csum", SET_DESIRED_VALUE_FOR_C_HERE ] }, 
                    then: "$$ROOT", 
                    else: { } 
                  } 
              } 

          } 
      } 
  }, /* (6) */
  { 
    $project: 
      { 
        "_id": 0,
        "docs": 
          { 
            $filter: 
              { 
                input: "$ds", 
                "as": "doc", 
                cond: { $lte: [ "$$doc.csum", { $min: "$gteC.csum" } ] }
              }
          }
      }
  }, /* (7) */
  { $unwind: "$docs" }, /* (8) */ 
  { $project: { "_id": "$docs._id", "c": "$docs.c" } } /* (9) */
]);

Kết quả

Giải thích

Ý tưởng cơ bản đằng sau nó là xây dựng mảng trợ giúp cho mỗi tài liệu trong bộ sưu tập ( giai đoạn 1-3 )

{ "_id" : 1, "c" : 2 } -> cs = [ 2 ]
{ "_id" : 2, "c" : 6 } -> cs = [ 2, 6 ]
{ "_id" : 3, "c" : 1 } -> cs = [ 2, 6, 1 ]

sử dụng $slice toán tử tổng hợp mảng và sau đó thay thế nó bằng tổng tất cả các phần tử mà nó chứa ( giai đoạn 4-5 )

{ "_id" : 1, "c" : 2 } -> csum = 2
{ "_id" : 2, "c" : 6 } -> csum = 8
{ "_id" : 3, "c" : 1 } -> csum = 9

sử dụng $unwind giai đoạn và $sum toán tử bộ tích lũy nhóm .

Sau đó, tạo một mảng tài liệu trợ giúp khác với csum >= C ( giai đoạn 6 )

/* Ex. (C = 8) */
gteC = [ { "_id" : 3, "c" : 1, "csum" : 9 }, { "_id" : 2, "c" : 6, "csum" : 8 } ]

Bước cuối cùng là truy xuất tất cả tài liệu bằng csum <= Min { gteC.csum } . Điều này được thực hiện bằng cách sử dụng $filter toán tử tổng hợp mảng ( giai đoạn 7 ).

Tuy nhiên, tôi không chắc chắn đây là hiệu quả nhất quy trình tổng hợp (sẽ biết ơn nếu có bất kỳ đề xuất cải tiến nào) để đạt được những gì bạn muốn.

Tái bút Trước khi kiểm tra truy vấn, đừng quên thay đổi tên của bộ sưu tập và thay thế SET_DESIRED_VALUE_FOR_C_HERE.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Lọc mảng bằng toán tử $ in trong giai đoạn $ project

  2. Hàm $ tuần và tổng hợp ngày đầu tiên của tuần

  3. MongoDB + Node.js:không thể chèn ngày đúng cách

  4. Mongo, tìm qua danh sách id

  5. Cách dễ nhất để cài đặt phần mở rộng Mongodb PHP trong Ubuntu 13.10 (saucy)?