Co chcete, je $cond operátor a několik vnořených podmínek s $and . Ale to by vám mělo dát přesně to, co chcete.
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 }}
])
Protože váš čas je celý milisekund můžete vidět, proč jsem požádal o úpravu.
Tedy jako $cond je ternární operátor, vyžaduje tři argumenty:
- Podmínka k vyhodnocení, která vrací logickou hodnotu
- Vrácená hodnota, kde je podmínka pravda
- Vrácená hodnota, kde je podmínka false
Myšlenka je tedy taková, že hnízdíte podmínky v celém textu, přechod na další test na false dokud nenajdete podmínku, která se má shodovat, a hodnotu, kterou chcete vrátit.
$and součástí je pole podmínek zahrnout. Tím získáte rozsahy . Takže v nejdelších částech:
{"$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
Kaskádové procházení vás times
ponechá na "Rychlý". pod 500 milisekund.
Každý z těchto keys
je odeslán do skupiny a my jen { $sum: 1 }
abyste získali počet, když jsou seskupeny.
Pokud to potřebujete ve své vlastní jazykové implementaci, celý pipeline
obsah v rámci
je pouze JSON, takže jej můžete analyzovat do své nativní datové struktury, pokud vám ruční překlad uniká, nebo pokud jste jako já jen líní.
UPRAVIT
Kvůli komentářům zdá se nutné vysvětlit formulář předloženého dotazu. Zde tedy pro upřesnění dodatek k úpravám.
Při učení použití agregačního kanálu a skutečně dobrý postup pro zápis a testování složitou řadu fází nebo logiky, považuji za užitečné vizualizovat výsledky implementací částí po jednotlivých krocích . Takže v případě psaní takové věci moje první krok by byl následující:
db.collection.aggregate([
{"$group": {
"_id": {"$cond": [
{"$gte": ["$LoadTime", 2000] },
"Slowest",
null
]}
}}
])
To by mi teď dalo počet „Nejpomalejší“, jak bych očekával, a pak kbelík vše ostatní do null
. Je tu tedy fáze, kdy zatím vidím výsledky. Ale při testování Vlastně bych udělal něco takového, než se pustím do budování řetězce:
db.collection.aggregate([
{"$group": {
"_id": {"$cond": [
{"$and": [
{"$lt": ["$LoadTime", 2000] },
{"$gte": ["$LoadTime", 1000] }
]},
"Slow",
null
]}
}}
])
Takže právě dostávám výsledky pro "Slow" (mezi 2000 a 1000) se vším ostatním v null
Kbelík. Takže můj celkový počet zůstává stejný.
Ve finále dotaz, jak bylo zdůrazněno, v ternární
podmínka, která je vnořena jako tato, první etapa již vyhodnoceno false
pro položky testované dalším operátor. To znamená, že nejsou větší než hodnota, která již byla testována v první fázi, a to eliminuje potřebu testovat tento stav, aby to mohlo být zapsán následovně:
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
A to zkraty hodnocení, protože žádné skutečné neexistuje potřebují otestovat věci, které neprojdou do další logické podmínky.
Tedy čistě z vizuálních důvodů a pro čistou lenost vyjmout a vložit logiky, skončíme s rozšířenou formou pomocí $and stav zabalit rozsah. Ale pro ty nejsou zvyklí použití ternary
existuje jasná vizuální vodítka že výsledky porovnávané v této fázi spadají mezi hodnoty 2000ms
a 1000ms
, a tak dále, což je to, co chcete jako výsledek v každém rozsahu.
Jak jsem řekl, zbytečné to mít kvůli tomu, jak funguje logika, ale bylo fázi vývoje a je jasný lidem, kteří se teprve rozejdou použití ternary formulář, který $cond poskytuje.