$first (aggregation)

On this page本页内容

Definition定义

$first

New in version 4.4.版本4.4中的新功能。

Returns the first element in an array.返回数组中的第一个元素。

Disambiguation消除歧义

The following page describes the array element operator $first. 下一页介绍数组元素运算符$firstFor the accumulator $first, available only with the $group stage, see $first (accumulator) instead.对于仅适用于$group阶段的累加器$first,请参阅$first(累加器)

See also参阅

$last

Syntax语法

$first has the following syntax:$first语法如下所示:

{ $first: <expression> }

The <expression> can be any valid expression as long as it resolves to an array, null or missing. <expression>可以是任何有效的表达式,只要它解析为数组(null或缺失)。For more information on expressions, see Expressions.有关表达式的详细信息,请参阅表达式

The $first operator is an alias for the following $arrayElemAt expression:$first运算符是以下$arrayElemAt表达式的别名:

{ $arrayElemAt: [ <arrary expression>, 0 ] }

Behavior行为

Valid Operands有效操作数

Valid operand for $first must resolve to an array, null, or missing$first的有效操作数必须解析为数组、null或缺失

  • If the operand resolves to a non-empty array, $first returns the first element in the array:如果操作数解析为非空数组,$first返回数组中的第一个元素:
  • If the operand resolves to an empty array [], $first does not return a value.如果操作数解析为空数组[]$first不返回值。
  • If the operand is null or missing, $first returns null.如果操作数为null或缺少,$first返回null

For example, create a test collection example1 with the following documents:例如,使用以下文档创建测试集合example1

db.example1.insertMany([
     { "_id" : 1, "x" : [ 1, 2, 3 ] },      // Non-empty array
     { "_id" : 2, "x" : [ [ ] ] },          // Non-empty array
     { "_id" : 3, "x" : [ null ] },         // Non-empty array
     { "_id" : 4, "x" : [ ] },              // Empty array
     { "_id" : 5, "x" : null },             // Is null
     { "_id" : 6 }                          // Is Missing
])

Then, the following adds a new field firstElem whose value is derived from applying the $first operator to the x field:然后,下面添加一个新字段firstElem,其值是通过将$first运算符应用于x字段得到的:

db.example1.aggregate([
   { $addFields: { firstElem: { $first: "$x" } } }
])

The operator returns the following documents:运算符返回以下文件:

{ "_id" : 1, "x" : [ 1, 2, 3 ], "firstElem" : 1 }
{ "_id" : 2, "x" : [ [ ] ], "firstElem" : [ ] }
{ "_id" : 3, "x" : [ null ], "firstElem" : null }
{ "_id" : 4, "x" : [ ] }                          // No output
{ "_id" : 5, "x" : null, "firstElem" : null }
{ "_id" : 6, "firstElem" : null }

Invalid Operands无效操作数

If the operand does not resolve to an array, null, or missing, the aggregation operation as a whole errors.如果操作数未解析为数组、null或缺失,则整个聚合操作将出错。

For example, create a test collection example2 with the following documents:例如,使用以下文档创建测试集合example2

db.example2.insertMany([
   { "_id" : 1, "x" : [ 1, 2, 3 ] },
   { "_id" : 2, "x" : 2 },             // x is not an array/null or missing
])

Then, the following aggregation operation returns an error because of the { "_id" : 2, "x" : 2 } document:然后,由于{ "_id" : 2, "x" : 2 }文档,以下聚合操作返回一个错误:

db.example2.aggregate( { $addFields: { firstElem: { $first: "$x" } } } )

That is, the operation returns the following:也就是说,该操作返回以下内容:

2020-01-20T18:31:13.431-05:00 E  QUERY    [js] uncaught exception: Error: command failed: {
   "ok" : 0,
   "errmsg" : "$first's argument must be an array, but is double",
   "code" : 28689,
   "codeName" : "Location28689"
} : aggregate failed :

Example示例

Create a sample collection runninglog with the following documents:使用以下文档创建样本集合runninglog

db.runninglog.insertMany([
   { "_id" : 1, "team" : "Anteater", log: [ { run: 1, distance: 8 }, { run2: 2, distance: 7.5 }, { run: 3, distance: 9.2 } ] },
   { "_id" : 2, "team" : "Bears", log: [ { run: 1, distance: 18 }, { run2: 2, distance: 17 }, { run: 3, distance: 16 } ] },
   { "_id" : 3, "team" : "Cobras", log: [ { run: 1, distance: 2 } ] }
])

The following aggregation uses the $first and $last operator on the log array to retrieve the information for the first run and the last run:以下聚合使用日志数组上的$first$last运算符来检索第一次运行和最后一次运行的信息:

db.runninglog.aggregate([
   { $addFields: { firstrun: { $first: "$log" }, lastrun: { $last: "$log" } } }
])

The operation returns the following results:操作返回以下结果:

{ "_id" : 1, "team" : "Anteater", "log" : [ { "run" : 1, "distance" : 8 }, { "run2" : 2, "distance" : 7.5 }, { "run" : 3, "distance" : 9.2 } ],
      "firstrun" : { "run" : 1, "distance" : 8 }, "lastrun" : { "run" : 3, "distance" : 9.2 } }
{ "_id" : 2, "team" : "Bears", "log" : [ { "run" : 1, "distance" : 18 }, { "run2" : 2, "distance" : 17 }, { "run" : 3, "distance" : 16 } ],
      "firstrun" : { "run" : 1, "distance" : 18 }, "lastrun" : { "run" : 3, "distance" : 16 } }
{ "_id" : 3, "team" : "Cobras", "log" : [ { "run" : 1, "distance" : 2 } ],
      "firstrun" : { "run" : 1, "distance" : 2 }, "lastrun" : { "run" : 1, "distance" : 2 } }

To calculate the change between the first and the last distances, the following operation uses $cond and $size operators to calculate the difference (i.e. $subtract) the two distances if there are two or more elements in the log array:为了计算第一个距离和最后一个距离之间的变化,以下操作使用$cond$size运算符来计算两个距离之间的差异(即,如果log数组中有两个或多个元素,则使用$subtract):

db.runninglog.aggregate([
  { $addFields: { firstrun: { $first: "$log" }, lastrun: { $last: "$log" } } },
  { $project: { team: 1, progress:
      {
        $cond: {
           if: { $gt: [ { $size:"$log" }, 1 ] } ,
           then: { $subtract: [ "$lastrun.distance", "$firstrun.distance"] },
           else: "Not enough data." }
      }

  }}
])

The operation returns the following documents:该操作将返回以下文档:

{ "_id" : 1, "team" : "Anteater", "progress" : 1.1999999999999993 }
{ "_id" : 2, "team" : "Bears", "progress" : -2 }
{ "_id" : 3, "team" : "Cobras", "progress" : "Not enough data." }

By default, the shell uses the 64-bit floating-point double for numbers. 默认情况下,shell对数字使用64位浮点双精度。To improve precision, you can use NumberDecimal instead.为了提高精度,可以改用NumberDecimal

See Also参阅