使用$ project时将值添加到数组

时间:2019-05-12 16:37:52

标签: javascript mongodb

我正在编写一条聚合管道以返回赢率。当我使用$ sum时,值是从 $ facet $ project 在数组中输出的。这让我感到困惑。为了解决这个问题,我在计算winRatio时只需在数组上运行$ sum,效果很好。 如何使用$ project而不将值添加到数组中?

Round.aggregate([
  {
    $match: {
      $and: query,
    },
  },
  {
    $facet: {
      wins: [
        {
          $match: {
            winner: user,
          },
        },
        {
          $group: {
            _id: { user: '$scores.player', game: '$game' },
            value: { $sum: 1 }, // value *not* within array
          },
        },
      ],
      rounds: [
        {
          $unwind: '$scores',
        },
        {
          $match: {
            'scores.player': user,
          },
        },
        {
          $group: {
            _id: { user: '$scores.player', game: '$game' },
            value: { $sum: 1 }, // value *not* within array
          },
        },
      ],
    },
  },
  {
    $project: {
      _id: '$rounds._id',
      rounds: '$rounds.value', // value within an array
      wins: '$wins.value',  // value within an array
      winRatio: { ... },
    },
  },
]);

模式:

const schema = new mongoose.Schema(
  {
    game: { type: mongoose.Schema.ObjectId, required: true },
    scores: [
      {
        player: { type: mongoose.Schema.ObjectId, ref: 'User', required: true },
        playerName: { type: String }, // denormalise
        score: { type: Number, required: true },
      },
    ],
    winner: { type: mongoose.Schema.ObjectId, required: true },
    datePlayed: { type: Date },
  },
  { timestamps: true },
);

1 个答案:

答案 0 :(得分:0)

您问为什么$sum'有效'和$project剂量。

让我们首先了解$ facet阶段的输出。

{ 
    "wins" : [
        {
            "_id" : {
                "user" : [
                    "player1", 
                    "player2"
                ], 
                "game" : 1.0
            }, 
            "value" : 2.0
        }
    ], 
    "rounds" : [
        {
            "_id" : {
                "user" : "player1", 
                "game" : 1.0
            }, 
            "value" : 3.0
        }
    ]
}

我们可以看到每个文档结果都是一个数组,即使您在最后将其分组,也可以将每个结果想象成它自己的聚合,返回值始终是一个数组(为空或不取决于结果)。

因此,当您在$project$rounds.value时,您是在告诉mongo在数组中保留每个结果的value字段。在我们的情况下,只有一个,但仍然如此。 另一方面,

$sum是来自文档的累积运算符:

  

使用单个表达式作为其操作数,如果表达式解析为数组,则$ sum遍历数组以对数组的数字元素进行操作以返回单个值。

快速解决您的“问题”只是在投影时添加$sum

{
    $project: {
      _id: '$rounds._id',
      rounds: {$sum: '$rounds.value'},
      wins: {$sum: '$wins.value'},
      winRatio: { ... },
    },
  },
相关问题