Ако искате да „претеглите“ резултатите по определени критерии или да имате някакъв вид „изчислена стойност“ в рамките на „сортиране“, тогава имате нужда от .aggregate()
вместо това метод. Това позволява да се използват "прогнозирани" стойности в $sort
операция, за която може да се използва само настоящо поле в документа:
db.messages.aggregate([
{ "$match": { "messages": userId } },
{ "$project": {
"recipients": 1,
"unread": 1,
"content": 1,
"readYet": {
"$setIsSubset": [ [userId], "$unread" ] }
}
}},
{ "$sort": { "readYet": -1 } },
{ "$limit": 20 }
])
Тук $setIsSubset
оператор позволява сравнение на "непрочетения" масив с конвертиран масив от [userId]
да видим дали има съвпадения. Резултатът ще бъде или true
където потребителският идентификатор съществува или false
където не е така.
След това може да се предаде на $sort
, който подрежда резултатите с предпочитание пред съвпаденията ( низходящо сортиране е true
отгоре) и накрая $limit
просто връща резултатите до определеното количество.
Така че, за да се използва изчислен термин за "сортиране", стойността трябва да бъде "проектирана" в документа, за да може да бъде сортирана. Рамката за агрегиране е начинът, по който правите това.
Също така имайте предвид, че $elemMatch
не се изисква само за съвпадение на една стойност в масива и трябва само да посочите стойността директно. Целта му е да бъдат изпълнени „множество“ условия за един елемент от масива, което разбира се не се прилага тук.