获取数组中第一个元素的最大值?

Getting the max for the first element in an array?

假设我有如下文件:

{
   email: "test@test.com",
   values: [2,9]
},
{
   email: "test@test.com",
   values: [1,3]
},
{
   email: "another@email.com",
   values: [4,5]
},

我想为每封电子邮件获取 values 数组中第一个元素的最大值(因此 2 对应 test@test.com。是否可以应用 $max 只到数组的第一个元素?我试过下面的方法:

db.test.aggregate({$group:{_id: '$email', max: {$max: "$values[0]"}}})

db.test.aggregate({$group:{_id: '$email', max: {$max: "$values.0"}}})

但两者似乎都不起作用(它们 return 或者 nullmax 的空数组)。这可以做到吗?

关闭尝试,但不幸的是,.find() 等方法可用的标准投影形式不适用于聚合框架。你必须多参与一点才能得到你想要的。

db.test.aggregate([
    // Unwind the arrays
    { "$unwind": "$values" },

    // Get the first value out of each document. Yes, order is respected.
    { "$group": {
        "_id": "$_id",
        "email": { "$first": "$email" },
        "firstValue": { "$first": "$values" }
    }},

    // Then get "max" per grouping key
    { "$group": {
        "_id": "$email",
        "value": { "$max": "$firstValue" }
    }}
])

这是有效的,因为 $first 在 "grouping boundary" 上拉取 "first" 匹配项,并且在展开数组内容时遵守数组的顺序。

因此,一旦这些值被提取,"first" $group stage gets the "first" array element in the document. And the "second" $group stage performs the $max 就会覆盖所有这些值。

P.S。不要问如何获得 "nth" 值,因为这完全是另一个问题,而且涉及更多。如果你遵循它,那么虽然这样做是合乎逻辑的。这不是最佳解决方案,但可以做到。

相信我,我们一直在等待 "slice" 预测和 "limits" 关于 $push 操作一段时间了。也许有一天会发生。

我会建议一个更短、更通用的解决方案,适用于数组的任何索引:

db.test.aggregate([
  {$project: {email: "$email", first_value:
      {$arrayElemAt: [ "$values", 0]}}},
  {$group: {_id: '$email', value: {$max: '$first_value'}}}
])