How Do I Sort A Collection Based On Values In An Array
I have collection named result with following values:- > db.result.findOne() { '_id' : ObjectId('53b05264421aa97e980ba404'), 'result' : [ {
Solution 1:
As you may have already tried, you cannot specify a specific item inside an array as a "key" to "sort" with a simple find. For this you are going to need the aggregate method in order to get the keys you want to sort on.
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
}}
])
So here you "extract" the matching values using the $cond
operator within a $max
statement after unwinding the array. The de-normalized documents do not all have the same values as they now represent the items in the array, so you test them.
With those extracted keys you can sort your whole documents again, and then finally discard those fields as you no longer need them.
Post a Comment for "How Do I Sort A Collection Based On Values In An Array"