карта mongodb уменьшить значение не определено - PullRequest
0 голосов
/ 24 октября 2019

У меня есть следующая коллекция в 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
}

Я хочу суммировать баллы за каждую игру в коллекции. Для этого я пытаюсь реализовать уменьшение карты следующим образом -

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

Я ожидаю сумму значений балловдля каждой игры. Что я тут не так делаю?

1 Ответ

1 голос
/ 24 октября 2019

Возможно, этот запрос может помочь?

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 }

** Если все еще хотите использовать mapreduce ... **

Основная проблема - вложенные данные. Нужно ссылаться на данные с точки зрения games.score. Для функции картографического уменьшения карты требуется такая логика.

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"});

Запрос:

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 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...