Группа агрегации MongoDB одновременно - PullRequest
0 голосов
/ 21 марта 2020

У меня есть документы, хранящиеся в mongodb, например:

{
  _id: ObjectId("abc"),
  teams: [{
    _id: ObjectId("aaa"),
    points: 10
  }, {
    _id: ObjectId("bbb"),
    points: 20
  }],
  players: [{
    hints: 2,
    team: ObjectId("aaa")
  }, {
    hints: 3,
    team: ObjectId("bbb")
  }]
}

Учитывая набор документов, я хочу извлечь командные очки и сумму подсказок их игроков. По сути, я хочу получить что-то вроде:

[{
  team: aaa,
  points: 10,
  hints: 2
}, {
  team: bbb,
  points: 20,
  hints: 3
}]

Где очки - это сумма «очков», полученных командой в каждом документе, а «подсказки» - сумма подсказок, полученных ее игроками. , Я могу добиться этого в двух запросах:

db.data.aggregate([ {$unwind: { "$players" }, 
                    {$group: { _id: "$players.team", hints: { $sum: "$player.hints" } } }])
[{ team: aaa, hints: 2 },{ team: bbb, hints: 3 }]
db.data.aggregate([ {$unwind: { "$teams" }, 
                    {$group: { _id: "$teams._id", points: { $sum: "$teams.points" } } }])
[{ team: aaa, points: 10 },{ team: bbb, points: 20 }]

Любая идея, чтобы достичь этого только с одним запросом?

1 Ответ

0 голосов
/ 21 марта 2020

Вы правильно выбрали 2 запроса и можете использовать $ facet , чтобы применить их в одном запросе. После этого вам нужно объединить массивы, затем развернуть и сгруппировать по идентификатору команды.

Вот запрос:

db.collection.aggregate([
  {
    $facet: {
      "points": [
        {
          $unwind: "$teams"
        },
        {
          $group: {
            _id: "$teams._id",
            points: {
              $sum: "$teams.points"
            }
          }
        },

      ],
      "hints": [
        {
          $unwind: "$players"
        },
        {
          $group: {
            _id: "$players.team",
            hints: {
              $sum: "$players.hints"
            }
          }
        }
      ]
    }
  },
  {
    $project: {
      merged: {
        $concatArrays: [
          "$points",
          "$hints"
        ]
      }
    }
  },
  {
    $unwind: "$merged"
  },
  {
    $group: {
      _id: "$merged._id",
      points: {
        $max: "$merged.points"
      },
      hints: {
        $max: "$merged.hints"
      }
    }
  }
])

Он выведет именно то, что вы хотите.

Пн go Детская площадка

...