Als u resultaten wilt "wegen" op basis van bepaalde criteria of een soort "berekende waarde" wilt hebben binnen een "sortering", dan heeft u de .aggregate()
nodig methode in plaats daarvan. Hierdoor kunnen "geprojecteerde" waarden worden gebruikt in de $sort
bewerking, waarvoor alleen een aanwezig veld in het document kan worden gebruikt:
db.messages.aggregate([
{ "$match": { "messages": userId } },
{ "$project": {
"recipients": 1,
"unread": 1,
"content": 1,
"readYet": {
"$setIsSubset": [ [userId], "$unread" ] }
}
}},
{ "$sort": { "readYet": -1 } },
{ "$limit": 20 }
])
Hier de $setIsSubset
operator maakt vergelijking mogelijk van de "ongelezen" array met een geconverteerde array van [userId]
om te zien of er overeenkomsten zijn. Het resultaat is ofwel true
waar de userId bestaat of false
waar dat niet het geval is.
Dit kan dan worden doorgegeven aan $sort
, die de resultaten rangschikt met voorkeur voor de overeenkomsten (aflopende sortering is true
bovenaan ), en tot slot $limit
retourneert gewoon de resultaten tot het gespecificeerde bedrag.
Dus om een berekende term voor "sorteren" te gebruiken, moet de waarde in het document worden "geprojecteerd", zodat er op kan worden gesorteerd. Het aggregatieraamwerk is hoe u dit doet.
Merk ook op dat $elemMatch
is niet vereist om slechts een enkele waarde binnen een array te matchen, en u hoeft de waarde alleen rechtstreeks op te geven. Het is bedoeld waar aan "meerdere" voorwaarden moet worden voldaan op een enkel array-element, wat hier natuurlijk niet van toepassing is.