Nếu bạn muốn "cân nhắc" kết quả theo các tiêu chí nhất định hoặc có bất kỳ loại "giá trị được tính toán" nào trong một "sắp xếp", thì bạn cần .aggregate()
thay vào đó. Điều này cho phép các giá trị "dự kiến" được sử dụng trong $sort
hoạt động mà chỉ một trường hiện tại trong tài liệu mới có thể được sử dụng:
db.messages.aggregate([
{ "$match": { "messages": userId } },
{ "$project": {
"recipients": 1,
"unread": 1,
"content": 1,
"readYet": {
"$setIsSubset": [ [userId], "$unread" ] }
}
}},
{ "$sort": { "readYet": -1 } },
{ "$limit": 20 }
])
Đây là $setIsSubset
toán tử cho phép so sánh mảng "chưa đọc" với một mảng được chuyển đổi của [userId]
để xem có trận đấu nào không. Kết quả sẽ là true
nơi userId tồn tại hoặc false
nơi nó không.
Sau đó, điều này có thể được chuyển đến $sort
, sắp xếp các kết quả theo thứ tự ưu tiên so với các kết quả phù hợp (sắp xếp giảm dần là true
trên cùng), và cuối cùng là $limit
chỉ trả về kết quả với số lượng được chỉ định.
Vì vậy, để sử dụng một thuật ngữ được tính toán cho "sắp xếp", giá trị cần được "chiếu" vào tài liệu để nó có thể được sắp xếp theo. Khung tổng hợp là cách bạn thực hiện việc này.
Cũng lưu ý rằng $elemMatch
không bắt buộc phải khớp với một giá trị duy nhất trong một mảng và bạn chỉ cần chỉ định trực tiếp giá trị. Mục đích của nó là nơi cần đáp ứng các điều kiện "nhiều" trên một phần tử mảng duy nhất, điều này tất nhiên không áp dụng ở đây.