Hvis du vil "vægte" resultater efter bestemte kriterier eller have nogen form for "beregnet værdi" inden for en "sortering", skal du bruge .aggregate()
metode i stedet for. Dette gør det muligt at bruge "projicerede" værdier i $sort
operation, som kun et eksisterende felt i dokumentet kan bruges til:
db.messages.aggregate([
{ "$match": { "messages": userId } },
{ "$project": {
"recipients": 1,
"unread": 1,
"content": 1,
"readYet": {
"$setIsSubset": [ [userId], "$unread" ] }
}
}},
{ "$sort": { "readYet": -1 } },
{ "$limit": 20 }
])
Her er $setIsSubset
operatoren tillader sammenligning af det "ulæste" array med et konverteret array af [userId]
for at se om der er nogen matcher. Resultatet vil enten være true
hvor bruger-id'et findes eller false
hvor det ikke gør det.
Dette kan derefter sendes til $sort
, som sorterer resultaterne med præference til matchene ( faldende sortering er true
øverst ), og til sidst $limit
returnerer blot resultaterne op til det angivne beløb.
Så for at bruge et beregnet udtryk for "sortér", skal værdien "projiceres" ind i dokumentet, så det kan sorteres efter. Aggregeringsrammen er, hvordan du gør dette.
Bemærk også, at $elemMatch
er ikke påkrævet kun for at matche en enkelt værdi i et array, og du behøver kun at angive værdien direkte. Dets formål er, hvor "flere" betingelser skal være opfyldt på et enkelt array-element, hvilket naturligvis ikke gælder her.