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

Sử dụng Giá trị động trong Tổng hợp

Yêu cầu chung ở đây là bao gồm phạm vi cho "month" các giá trị được xem xét trong đó nó "lớn hơn" -5 tháng "trước" và "nhỏ hơn" +2 tháng "sau" như được ghi trong "enrolled" các mục nhập mảng.

Vấn đề là vì các giá trị này dựa trên "dateJoined" , chúng cần được điều chỉnh theo khoảng thời gian chính xác giữa "dateJoined""dateActivated" . Điều này làm cho biểu thức hiệu quả:

monthsDiff = (yearActivated - yearJoined)*12 + (monthActivated - monthJoined)

where month >= ( startRange + monthsDiff ) and month <= ( endRange + monthsDiff )
and enrolled = "01"

Hoặc được diễn đạt một cách logic "Các tháng giữa phạm vi được thể hiện được điều chỉnh bằng số tháng chênh lệch giữa việc tham gia và kích hoạt" .

Như đã nêu trong nhận xét, điều đầu tiên bạn cần làm ở đây là lưu trữ các giá trị ngày đó dưới dạng BSON Date trái ngược với các giá trị "chuỗi" rõ ràng hiện tại của chúng. Sau khi hoàn tất, bạn có thể áp dụng phép tổng hợp sau để tính toán sự khác biệt so với các ngày đã cung cấp và lọc phạm vi đã điều chỉnh cho phù hợp từ mảng trước khi tính:

var rangeStart = -5,
    rangeEnd = 2;

db.getCollection('enrollments').aggregate([
  { "$project": {
    "enrollments": {
      "$size": {
        "$filter": {
          "input": "$enrolled",
          "as": "e",
          "cond": {
            "$let": {
              "vars": {
                "monthsDiff": {
                  "$add": [
                    { "$multiply": [
                      { "$subtract": [
                        { "$year": "$dateActivated" },
                        { "$year": "$dateJoined" }
                      ]},
                      12
                    }},
                    { "$subtract": [
                      { "$month": "$dateActivated" },
                      { "$month": "$dateJoined" }
                    ]}
                  ]
                }
              },
              "in": {
                "$and": [
                  { "$gte": [ { "$add": [ rangeStart, "$$monthsDiff" ] }, "$$e.month" ] },
                  { "$lte": [ { "$add": [ rangeEnd, "$$monthsDiff" ] }, "$$e.month" ] },
                  { "$eq": [ "$$e.enrolled", "01" ] }
                ]
              }
            }
          } 
        }
      }
    }
  }}
])

Vì vậy, điều này áp dụng cùng một $filter vào mảng mà bạn đang cố gắng, nhưng bây giờ cũng tính đến các giá trị đã điều chỉnh trong phạm vi tháng để lọc.

Để giúp bạn đọc dễ dàng hơn, chúng tôi áp dụng $let cho phép tính toán giá trị chung thu được cho $$monthsDiff như được triển khai trong một biến. Đây là nơi áp dụng biểu thức được giải thích ban đầu, sử dụng $year $month để trích xuất các giá trị số đó từ các ngày được lưu trữ.

Sử dụng các toán tử toán học bổ sung $add , $subtract $multiply bạn có thể tính toán cả chênh lệch theo tháng và sau đó cũng có thể áp dụng để điều chỉnh các giá trị "phạm vi" trong điều kiện logic với $gte $lte .

Cuối cùng, vì $filter tạo ra một mảng chỉ gồm các mục nhập phù hợp với các điều kiện, để "đếm", chúng tôi áp dụng $size trả về độ dài của mảng "đã lọc", là "số lượng" kết quả phù hợp.

Tùy thuộc vào mục đích dự định của bạn, toàn bộ biểu thức cũng có thể được cung cấp trong đối số cho $sum với tư cách là $group tích lũy, nếu sau đó thực sự là ý định.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Không thể khóa tài liệu mongodb. Nếu tôi cần thì sao?

  2. MongoException:không cho phép các khóa có độ dài bằng 0, bạn đã sử dụng $ với dấu ngoặc kép chưa?

  3. Nơi lưu trữ MongoClient ở Django

  4. Làm thế nào để cập nhật một số lượng lớn tài liệu trong MongoDB một cách hiệu quả nhất?

  5. So sánh các mảng và trả về sự khác biệt