Json mongodb映射减少值未定义

Json mongodb映射减少值未定义,json,mongodb,nosql,Json,Mongodb,Nosql,我在mongodb有以下收藏- > db.games.find().pretty(); { "_id" : ObjectId("5db06c02e08772b58596ec72"), "name" : "Cricket", "genre" : "sport", "rating" : 10 } { "_id" : ObjectId("5db06c02e08772b58596ec73"), "name" : "Football", "ge

我在mongodb有以下收藏-

> db.games.find().pretty();
{
    "_id" : ObjectId("5db06c02e08772b58596ec72"),
    "name" : "Cricket",
    "genre" : "sport",
    "rating" : 10
}
{
    "_id" : ObjectId("5db06c02e08772b58596ec73"),
    "name" : "Football",
    "genre" : "sport",
    "rating" : 100,
    "achievement" : "champion",
    "games" : [
        {
            "score" : 20
        },
        {
            "score" : 30
        },
        {
            "score" : 22
        },
        {
            "score" : 145
        }
    ]
}
{
    "_id" : ObjectId("5db06c02e08772b58596ec74"),
    "name" : "Ludo",
    "genre" : "indoor",
    "rating" : 1
}
{
    "_id" : ObjectId("5db06c02e08772b58596ec75"),
    "name" : "Badminton",
    "genre" : "indoor",
    "rating" : 60,
    "games" : [
        {
            "score" : 34
        },
        {
            "score" : 12
        },
        {
            "score" : 50
        }
    ]
}
{
    "_id" : ObjectId("5db06c02e08772b58596ec76"),
    "name" : "Swimming",
    "genre" : "water",
    "rating" : 50
}
{
    "_id" : ObjectId("5db06c02e08772b58596ec77"),
    "name" : "Running",
    "genre" : "atheletics",
    "rating" : 70
}
{
    "_id" : ObjectId("5db06c02e08772b58596ec78"),
    "name" : "Shotput",
    "genre" : "atheletics",
    "rating" : 66
}
我想要收集每个游戏的分数总和。为此,我尝试实现map-reduce,如下所示-

> db.games.mapReduce( function(){emit(this.name,this.score)}, function(key,values) {return Array.sum(values)}, {out:"out_scores"});
{
    "result" : "out_scores",
    "timeMillis" : 330,
    "counts" : {
        "input" : 7,
        "emit" : 7,
        "reduce" : 0,
        "output" : 7
    },
    "ok" : 1
}
db.out_scores.find().pretty();
{ "_id" : "Badminton", "value" : undefined }
{ "_id" : "Cricket", "value" : undefined }
{ "_id" : "Football", "value" : undefined }
{ "_id" : "Ludo", "value" : undefined }
{ "_id" : "Running", "value" : undefined }
{ "_id" : "Shotput", "value" : undefined }
{ "_id" : "Swimming", "value" : undefined }
但结果集合中的值未定义如下-

> db.games.mapReduce( function(){emit(this.name,this.score)}, function(key,values) {return Array.sum(values)}, {out:"out_scores"});
{
    "result" : "out_scores",
    "timeMillis" : 330,
    "counts" : {
        "input" : 7,
        "emit" : 7,
        "reduce" : 0,
        "output" : 7
    },
    "ok" : 1
}
db.out_scores.find().pretty();
{ "_id" : "Badminton", "value" : undefined }
{ "_id" : "Cricket", "value" : undefined }
{ "_id" : "Football", "value" : undefined }
{ "_id" : "Ludo", "value" : undefined }
{ "_id" : "Running", "value" : undefined }
{ "_id" : "Shotput", "value" : undefined }
{ "_id" : "Swimming", "value" : undefined }

我期望每场比赛的得分总和。我做错了什么?

也许这个查询会有所帮助

db.games.aggregate(
[
    { $unwind: { path: "$games", preserveNullAndEmptyArrays: true }},
    { $group: {
        _id: "$name",
        score: { $sum:  "$games.score" }
    }}
])
结果:

{ "_id" : "Shotput", "score" : 0 }
{ "_id" : "Running", "score" : 0 }
{ "_id" : "Ludo", "score" : 0 }
{ "_id" : "Swimming", "score" : 0 }
{ "_id" : "Badminton", "score" : 96 }
{ "_id" : "Football", "score" : 217 }
{ "_id" : "Cricket", "score" : 0 }
db.out_scores.find()
{ "_id" : "Badminton", "value" : 96 }
{ "_id" : "Cricket", "value" : 0 }
{ "_id" : "Football", "value" : 217 }
{ "_id" : "Ludo", "value" : 0 }
{ "_id" : "Running", "value" : 0 }
{ "_id" : "Shotput", "value" : 0 }
{ "_id" : "Swimming", "value" : 0 }
**如果仍要使用mapreduce**

根本问题是嵌套数据。需要从games.score的角度参考数据。map reduce的映射功能需要这种逻辑

db.games.mapReduce( function(){
  var sum_of_score = 0;

  if (this.games != undefined) {
    for (var i=0; i<this.games.length; i++) {
      sum_of_score += this.games[i].score;
    }
  }
  emit(this.name, sum_of_score)
}, function(key, values) { }, {out:"out_scores"});
结果:

{ "_id" : "Shotput", "score" : 0 }
{ "_id" : "Running", "score" : 0 }
{ "_id" : "Ludo", "score" : 0 }
{ "_id" : "Swimming", "score" : 0 }
{ "_id" : "Badminton", "score" : 96 }
{ "_id" : "Football", "score" : 217 }
{ "_id" : "Cricket", "score" : 0 }
db.out_scores.find()
{ "_id" : "Badminton", "value" : 96 }
{ "_id" : "Cricket", "value" : 0 }
{ "_id" : "Football", "value" : 217 }
{ "_id" : "Ludo", "value" : 0 }
{ "_id" : "Running", "value" : 0 }
{ "_id" : "Shotput", "value" : 0 }
{ "_id" : "Swimming", "value" : 0 }

谢谢你的回答@barrypicker,但我想用map reduce来做。你知道为什么Map reduce不起作用吗???@DevashishPrasad-更新了我的答案,加入了一个正在运行的mapreduce,但它不起作用…原因是什么?为什么不减少?我提到了实现map reduce。这几乎是同样的方式。@devahishprasad-我的错误,我把逻辑放在了错误的映射函数中。我已经更新了我的答案。部分挑战是某些文档缺少此元素,因此“未定义”会阻止整个过程。出于这个原因,我将evaluate包装在一个“if”语句中,以首先检查未定义的。