如何根据数组中的值对集合进行排序

时间:2014-07-09 01:18:37

标签: python mongodb sorting mongodb-query aggregation-framework

我有一个名为result的集合,其中包含以下值: -

> db.result.findOne()
{
        "_id" : ObjectId("53b05264421aa97e980ba404"),
        "result" : [
                {
                        "attempted" : 49,
                        "subject_total_marks" : 50,
                        "score" : 15,
                        "correct_subject_answer" : 15,
                        "subject" : "Biology"
                },
                {
                        "attempted" : 30,
                        "subject_total_marks" : 30,
                        "score" : 4,
                        "correct_subject_answer" : 4,
                        "subject" : "Chemistry"
                },
                {
                        "attempted" : 20,
                        "subject_total_marks" : 20,
                        "score" : 7,
                        "correct_subject_answer" : 7,
                        "subject" : "Physics"
                },
                {
                        "attempted" : 99,
                        "correct_subject_answer" : 26,
                        "score" : 26,
                        "subject_total_marks" : 100,
                        "subject" : "Total"
                }
        ],
        "useruid" : NumberLong(548),
        "exam_code" : 301,
        "ess_time" : 1404062120
}

现在我想根据"得分"对系列进行排序。 "总计"这是结果数组内部。然后根据物理,数学的分数,然后基于化学,最后生物学进行排序。

1 个答案:

答案 0 :(得分:3)

正如您可能已经尝试过的那样,您不能将数组中的特定项指定为使用简单查找“排序”的“键”。为此,您需要使用聚合方法来获取要排序的键。

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
     }}
])

因此,在展开数组后,您可以在$cond语句中使用$max运算符“提取”匹配值。取消规范化的文档并不都具有与它们现在表示数组中的项目相同的值,因此您可以对它们进行测试。

使用这些提取的密钥,您可以再次对整个文档进行排序,然后最终丢弃这些字段,因为您不再需要它们。

相关问题