Jeśli chcesz „zważyć” wyniki według określonych kryteriów lub mieć jakąkolwiek „obliczoną wartość” w ramach „sortowania”, potrzebujesz .aggregate()
zamiast tego. Pozwala to na użycie "odwzorowanych" wartości w $sort
operacja, dla której można wykorzystać tylko obecne pole w dokumencie:
db.messages.aggregate([
{ "$match": { "messages": userId } },
{ "$project": {
"recipients": 1,
"unread": 1,
"content": 1,
"readYet": {
"$setIsSubset": [ [userId], "$unread" ] }
}
}},
{ "$sort": { "readYet": -1 } },
{ "$limit": 20 }
])
Tutaj $setIsSubset
operator umożliwia porównanie „nieprzeczytanej” tablicy z przekonwertowaną tablicą [userId]
aby sprawdzić, czy są jakieś dopasowania. Wynik będzie albo true
gdzie istnieje identyfikator użytkownika lub false
gdzie nie.
Można to następnie przekazać do $sort
, który porządkuje wyniki z preferencją do dopasowań ( sortowanie malejąco jest true
na górze ) i wreszcie $limit
po prostu zwraca wyniki do określonej kwoty.
Aby więc użyć wyliczonego terminu dla „sortowania”, wartość musi zostać „odwzorowana” na dokument, aby można było ją posortować. Sposób agregacji to sposób, w jaki to robisz.
Pamiętaj też, że $elemMatch
nie jest wymagane tylko do dopasowania pojedynczej wartości w tablicy, a wystarczy określić bezpośrednio wartość. Jego celem jest spełnienie „wielu” warunków na jednym elemencie tablicy, co oczywiście nie ma tutaj zastosowania.