To, czego potrzebujesz, to $cond operator i sporo warunków zagnieżdżonych z $and . Ale to powinno dać ci dokładnie to, czego chcesz.
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 }}
])
Ponieważ Twój czas jest cały milisekundy możesz zobaczyć, dlaczego poprosiłem o edycję.
Tak jak $cond jest trójargumentem operatora, potrzebne są trzy argumenty:
- Warunek do oceny, który zwraca wartość logiczną
- Wartość zwracana, gdy warunek jest prawda
- Wartość zwracana, gdy warunek jest fałsz
Dlatego chodzi o to, aby zagnieździć warunki przez cały czas, przechodząc do następnego test na fałsz dopóki nie znajdziesz warunku do dopasowania i wartości do zwrócenia.
$i część to tablica warunków zawrzeć. Daje to zakresy . Więc w najdłuższych częściach:
{"$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
Kaskadowo przez ciebie pozostaje "Szybko" na times
poniżej 500 milisekund.
Każdy z tych keys
jest emitowany do grupy i po prostu { $sum: 1 }
aby uzyskać liczbę, ponieważ są one zgrupowane.
Jeśli potrzebujesz tego we własnej implementacji języka, cały pipeline
zawartość w
to po prostu JSON, więc możesz przetworzyć go do swojej natywnej struktury danych, jeśli nie masz możliwości tłumaczenia ręcznego lub jeśli tak jak ja jesteś po prostu leniwy.
EDYTUJ
Ze względu na komentarze wydaje się konieczne wyjaśnienie formularza prezentowanego zapytania. Oto dodatek do edycji w celu wyjaśnienia.
Kiedy nauka wykorzystanie potoku agregacji i rzeczywiście dobra praktyka do pisania i testowania złożonej serii etapów lub logiki, uważam, że warto wizualizować wyniki poprzez implementację części jeden krok na raz . Więc w przypadku pisania czegoś takiego mój pierwszy krok byłby następujący:
db.collection.aggregate([
{"$group": {
"_id": {"$cond": [
{"$gte": ["$LoadTime", 2000] },
"Slowest",
null
]}
}}
])
Teraz dałoby mi to liczbę „najwolniej”, zgodnie z oczekiwaniami, a następnie zasobnik wszystko inne w null
. Jest więc etap, na którym widzę dotychczasowe wyniki. Ale podczas testowania Właściwie zrobiłbym coś takiego, zanim przejdę do budowania łańcucha:
db.collection.aggregate([
{"$group": {
"_id": {"$cond": [
{"$and": [
{"$lt": ["$LoadTime", 2000] },
{"$gte": ["$LoadTime", 1000] }
]},
"Slow",
null
]}
}}
])
Otrzymuję więc tylko wyniki dla słowa „Powoli” (pomiędzy 2000 i 1000) ze wszystkim innym w null
wiaderko. Więc moja ogólna liczba pozostaje taka sama.
W finale zapytanie, jak wskazano, w trójargumentowym
warunek zagnieżdżony, taki jak ten, pierwszy etap ma już oceniane false
dla przedmiotów testowanych przez następne operator. Oznacza to, że nie większe niż wartość, która była już testowana w pierwszym etapie, co eliminuje potrzebę testowania tego stanu, więc może być napisane w następujący sposób:
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
I że zwarcia ocena, ponieważ nie ma prawdziwego musisz przetestować pod kątem rzeczy, które nie przejdą do następnego warunku logicznego.
Więc czysto z powodów wizualnych i za zwykłe lenistwo wytnij i wklej logiki, kończymy z rozwiniętym formularzem za pomocą $i warunek zawinięcia Zakres. Ale dla tych nieprzyzwyczajonych użycie trójnego
ponieważ istnieje wyraźna wskazówka wizualna że wyniki dopasowywane w tej fazie będą znajdować się między wartości 2000ms
i 1000ms
, i tak dalej, czego oczekujesz jako wynik w każdym zakresie.
Jak powiedziałem, niepotrzebne ze względu na działanie logiki, ale było faza rozwoju i jest jasne do ludzi, którzy jeszcze nie zajęli się nimi użycie trójnego formować $cond zapewnia.