Jak być może już próbowałeś, nie możesz określić określonego elementu w tablicy jako „klucza” do „sortowania” za pomocą prostego wyszukiwania. W tym celu będziesz potrzebować metody agregującej, aby uzyskać klucze, według których chcesz sortować.
db.exam.aggregate([
# Unwind to de-normalize
{ "$unwind": "$result" },
# Group back to the document and extract each score
{ "$group": {
"_id": "$_id",
"result": { "$push": "$result" },
"useruid": { "$first": "$useruid" },
"exam_code": { "$first": "$exam_code" },
"ess_time": { "$first": "$ess_time" },
"Total": {
"$max": {
"$cond": [
{ "$eq": [ "$result.subject", "Total" ] },
"$result.score",
0
]
}
},
"Physics": {
"$max": {
"$cond": [
{ "$eq": [ "$result.subject", "Physics" ] },
"$result.score",
0
]
}
},
"Mathematics": {
"$max": {
"$cond": [
{ "$eq": [ "$result.subject", "Mathematics" ] },
"$result.score",
0
]
}
},
"Chemistry": {
"$max": {
"$cond": [
{ "$eq": [ "$result.subject", "Chemistry" ] },
"$result.score",
0
]
}
},
"Biology": {
"$max": {
"$cond": [
{ "$eq": [ "$result.subject", "Biology" ] },
"$result.score",
0
]
}
}
}},
# Sort on those scores
{ "$sort": {
"Total": -1,
"Physics": -1,
"Mathematics": -1,
"Chemistry": -1,
"Biology": -1
}},
# Project final wanted fields
{ "$project": {
"result": 1,
"useruid": 1,
"exam_code": 1,
"ess_time": 1
}}
])
Tak więc tutaj „wyodrębniasz” pasujące wartości za pomocą $cond
operator w $max
instrukcja po rozwinięciu tablicy. Nie wszystkie zdenormalizowane dokumenty mają te same wartości, które reprezentują teraz elementy w tablicy, więc je testujesz.
Za pomocą tych wyodrębnionych kluczy możesz ponownie posortować całe dokumenty, a następnie odrzucić te pola, ponieważ już ich nie potrzebujesz.