Pokud chcete „vážit“ výsledky podle určitých kritérií nebo mít v rámci „třídění“ jakýkoli druh „vypočítané hodnoty“, potřebujete .aggregate()
místo toho. To umožňuje použití "promítnutých" hodnot v $sort
operace, pro kterou lze použít pouze přítomné pole v dokumentu:
db.messages.aggregate([
{ "$match": { "messages": userId } },
{ "$project": {
"recipients": 1,
"unread": 1,
"content": 1,
"readYet": {
"$setIsSubset": [ [userId], "$unread" ] }
}
}},
{ "$sort": { "readYet": -1 } },
{ "$limit": 20 }
])
Zde je $setIsSubset
operátor umožňuje porovnání "nepřečteného" pole s převedeným polem [userId]
zjistit, zda existují nějaké shody. Výsledek bude buď true
kde userId existuje nebo false
kde tomu tak není.
To pak může být předáno $sort
, který seřadí výsledky přednostně před shodami (sestupné řazení je true
nahoře ) a nakonec $limit
pouze vrátí výsledky až do zadané částky.
Aby bylo možné použít vypočítaný termín pro „třídění“, musí být hodnota „promítnuta“ do dokumentu, aby ji bylo možné třídit. Agregační rámec je způsob, jak to udělat.
Všimněte si také, že $elemMatch
není vyžadováno pouze k tomu, aby odpovídalo jedné hodnotě v poli, a stačí zadat hodnotu přímo. Jeho účelem je, aby na jednom prvku pole bylo potřeba splnit "více" podmínek, což zde samozřejmě neplatí.