Điều bạn muốn là $ cond toán tử và khá nhiều điều kiện lồng nhau với $ và . Nhưng điều này sẽ cung cấp cho bạn chính xác những gì bạn muốn.
db.collection.aggregate([
{"$group": {
"_id": {"$cond": [
{"$gte": ["$LoadTime", 2000] },
"Slowest", // return "Slowest" where true
{"$cond": [
{"$and": [
{"$lt": ["$LoadTime", 2000] },
{"$gte": ["$LoadTime", 1000] }
]},
"Slow", // then "Slow" here where true
{"$cond": [
{"$and": [
{"$lt": ["$LoadTime", 1000] },
{"$gte": ["$LoadTime", 500 ] }
]},
"Medium", // then "Medium" where true
"Fast" // and finally "Fast" < 500
]}
]}
]},
"count": {"$sum": 1}
}},
{"$sort": { "count": 1 }}
])
Vì thời gian của bạn là toàn bộ mili giây bạn có thể thấy lý do tại sao tôi yêu cầu chỉnh sửa.
Vì vậy, với tư cách là $ cond là một ternary toán tử, nó có ba đối số là:
- Một điều kiện để đánh giá cái nào trả về boolean
- Giá trị trả về trong đó điều kiện là đúng
- Giá trị trả về trong đó điều kiện là sai
Do đó, ý tưởng là bạn tổ các điều kiện xuyên suốt, chuyển sang tiếp theo thử nghiệm trên false cho đến khi bạn tìm thấy một điều kiện để phù hợp và một giá trị để trả về.
$ và một phần là một mảng điều kiện bao gồm. Điều này cung cấp cho bạn phạm vi . Vì vậy, trong các phần dài nhất:
{"$cond": [ // Evaluate here
{"$and": [ // Within the range of the next 2
{"$lt": ["$LoadTime", 2000] },
{"$gte": ["$LoadTime", 1000] }
]},
"Slow", // true condition - return
{"$cond": [ // false - move to next eval
Xếp tầng qua bạn còn lại là "Nhanh" trong times
dưới 500 mili giây.
Mỗi keys
này được phát cho nhóm và chúng tôi chỉ { $sum: 1 }
để được tính khi chúng được nhóm lại với nhau.
Nếu bạn cần điều đó trong triển khai ngôn ngữ của riêng mình, toàn bộ pipeline
nội dung bên trong
chỉ là JSON, vì vậy bạn có thể phân tích cú pháp đó thành cấu trúc dữ liệu gốc của mình nếu việc dịch thủ công khiến bạn không hiểu hoặc nếu giống như tôi, bạn chỉ lười biếng.
CHỈNH SỬA
Do nhận xét có vẻ như cần giải thích về biểu mẫu của truy vấn được trình bày. Vì vậy, đây là phụ lục chỉnh sửa để làm rõ.
Khi học tập sử dụng đường ống tổng hợp và thực sự là phương pháp hay để viết ra và kiểm tra một loạt các giai đoạn hoặc lôgic phức tạp, tôi thấy rằng việc hình dung rất hữu ích kết quả bằng cách triển khai các phần từng bước một . Vì vậy, trong trường hợp viết một điều như vậy đầu tiên của tôi bước sẽ như sau:
db.collection.aggregate([
{"$group": {
"_id": {"$cond": [
{"$gte": ["$LoadTime", 2000] },
"Slowest",
null
]}
}}
])
Bây giờ, điều đó sẽ cung cấp cho tôi số lượng "Chậm nhất" như tôi mong đợi và sau đó là xô mọi thứ khác thành null
. Vì vậy, có một giai đoạn mà tôi nhìn thấy kết quả cho đến nay. Nhưng khi thử nghiệm Tôi thực sự sẽ làm điều gì đó như thế này trước khi chuyển sang xây dựng chuỗi:
db.collection.aggregate([
{"$group": {
"_id": {"$cond": [
{"$and": [
{"$lt": ["$LoadTime", 2000] },
{"$gte": ["$LoadTime", 1000] }
]},
"Slow",
null
]}
}}
])
Vì vậy, tôi chỉ nhận được kết quả cho "Chậm" ( giữa 2000 và 1000) với mọi thứ khác trong null
Gầu múc. Vì vậy, tổng số của tôi vẫn không đổi.
Trong trận chung kết , như đã được chỉ ra, trong ternary
điều kiện được lồng vào nhau chẳng hạn như điều kiện này, đầu tiên giai đoạn đã đã đã đánh giá false
cho các mục đang được kiểm tra bởi tiếp theo nhà điều hành. Điều này có nghĩa là chúng không lớn hơn giá trị đã được kiểm tra trong lần đầu tiên và điều đó không cần thiết phải kiểm tra điều kiện đó để điều này có thể được viết như sau:
db.collection.aggregate([
{"$group": {
"_id": {"$cond": [
{"$gte": ["$LoadTime", 2000] }, // Caught everything over 2000
"Slowest",
{"$cond": [
{"$gte": ["$LoadTime", 1000] } // Catch things still over 1000
"Slow",
{"$cond": [ // Things under 1000 go here
// and so on
Và đoản mạch đánh giá như không có thực cần phải kiểm tra những thứ không đạt đến điều kiện logic tiếp theo.
Vì vậy, hoàn toàn vì lý do trực quan và vì sự lười biếng tuyệt đối của cắt và dán logic, chúng tôi kết thúc với biểu mẫu mở rộng bằng cách sử dụng $ và điều kiện để quấn phạm vi. Nhưng đối với những người không quen việc sử dụng ternary
có một gợi ý trực quan rõ ràng rằng các kết quả được đối sánh trong giai đoạn này sẽ nằm giữa các giá trị của 2000ms
và 1000ms
, v.v., đó là kết quả bạn muốn trong mỗi phạm vi.
Như tôi đã nói, không cần thiết phải có vì cách logic hoạt động, nhưng nó đã giai đoạn phát triển và rõ ràng cho những người vẫn chưa quan tâm đến việc sử dụng ternary tạo thành $ cond cung cấp.