Mongodb - 从嵌套项中获得最高结果

Mongodb - getting highest result from nested item

我需要从各种评分中获得用户最高分。 这是一个示例 mongo 数据集:

{
    _id: "peter",
    name: "Peter Griffin",
    scores : [
        {
           event: "Peter Copter race",
           score: 100,
        },
        {
           event: "World domination",
           score: 0,
        },
        {
           event: "Listening",
           score: 10,
        }
    ]
},
{
   _id: "stewie",
   name: "Stuart Griffin",
   scores : [
       {
           event: "Peter Copter race",
           score: 0,
       },
       {
           event: "World domination",
           score: 1000,
       },
       {
           event: "Listening",
           score: 100,
       }
   ]
}

我想得到每个用户的最高分,返回类似

[{"_id": "peter", "top_score" : 100}, {"_id": "stewie", "top_score" : 1000}]

这是我目前得到的:

   db.famguyMongo.find({ "scores": { $exists: true } }).forEach(function(famMember) {
    var newScore = 0
    famMember.scores.forEach(function(getScore) {
        newScore = {$max: getScore.score}
    });
    print(newScore )
    newScore = 0
});

如您所见,我试图设置一个每次都要检查的变量。我也试过这个:

db.famguyMongo.find({ "scores": { $exists: true } }).forEach(function(famMember) {
    var newScore = 0
    famMember.scores.forEach(function(getScore) {
        newScore = { $cond: { $gte: [getScore.score, newScore] } getScore.score, 0 }
    });
    print(newScore)
    newScore = 0
});

您可以尝试 MongoDB 的 aggregation framework to calculate the maximum score per user. In your aggregation pipeline, the first step is to deconstruct the scores array field from the input documents using the $unwind operator to output a document for each element that you can then aggregate on later down the pipeline. Each output document replaces the array with an element value. The next pipeline stage will be the $group operator where you can then calculate the highest score using the $max aggregation operator on the scores.score field. The final step is the $project 操作,您可以在其中重塑流中的每个文档以以适当的格式显示所需的字段:

db.collection.aggregate([
    {
        "$unwind": "$scores"
    },
    {
        "$group": {
            "_id": "$_id",
            "highest_score": { "$max": "$scores.score" }
        }
    },
    {
        "$project": {
            "_id": 0,
            "name": "$_id",
            "highest_score": 1
        }
    }
]);

结果:

/* 0 */
{
    "result" : [ 
        {
            "highest_score" : 1000,
            "name" : "stewie"
        }, 
        {
            "highest_score" : 100,
            "name" : "peter"
        }
    ],
    "ok" : 1
}

我建议使用 ,但如果您想要 JavaScript 替代方案;

var objScores = {}; //Instantiate object
db.test.find({ "scores": { $exists: true } }).forEach(function(famMember) {
    var newScore = 0;
    objScores[famMember._id] = 0; //Set default for each person as score 0
    famMember.scores.forEach(function(getScore) { //loop through persons score
        if( getScore.score > objScores[famMember._id] ) {
            objScores[famMember._id] = getScore.score; //Record the highest score
        }
    });
});
print( objScores ); //print output

输出将是;

{
    "peter" : 100,
    "stewie" : 1000
}