$first (aggregation)
On this page本页内容
Definition定义
$first
Changed in version 5.0.5.0版更改。
Returns the result of an expression for the first document in a group of documents. Only meaningful when documents are in a defined order.返回一组文档中第一个文档的表达式结果。只有当文档按定义的顺序排列时才有意义。
$first
is available in these stages:可在以下阶段使用:
$bucket
$bucketAuto
$group
$setWindowFields
(Available starting in MongoDB 5.0)(从MongoDB 5.0开始提供)
Syntax语法
$first
syntax:
{ $first: <expression> }
Behaviors行为
Defining Document Order定义文档顺序
Array Operator数组运算符
If the expression resolves to an array:如果表达式解析为数组:
For a group of documents,对于一组文档,$first
returns the entire array from the first document.$first
从第一个文档返回整个数组。It does not traverse array elements.它不遍历数组元素。This is the case with stages like像$group
and$setWindowFields
.$group
和$setWindowFields
这样的阶段就是这样。For an individual document,对于单个文档,$first
returns the first element of the array.$first
返回数组的第一个元素。This is the case with stages like像$addFields
.$addFields
这样的阶段就是这样。
Missing Values缺少值
Documents in a group may be missing fields or may have fields with missing values.组中的文档可能缺少字段,也可能具有缺少值的字段。
If there are no documents from the prior pipeline stage, the如果没有来自上一个管道阶段的文档,$group
stage returns nothing.$group
阶段将不返回任何内容。If the field that the如果$first
accumulator is processing is missing,$first
returnsnull
.$first
累加器正在处理的字段丢失,$first
将返回null
。When used with与$setWindowFields
,$first
returnsnull
for empty windows. For example, when you have a{ documents:[ -1, -1] }
documents
window on the first document of a partition.$setWindowFields
一起使用时,$first
会为空窗口返回null
。例如,当分区的第一个文档上有一个documents
窗口{ documents:[ -1, -1] }
时。
For more information, see the Missing Data example later in this topic.有关详细信息,请参阅本主题后面的缺少数据示例。
Examples实例
Use in $group
Stage在$group
阶段中使用
$group
StageCreate the 创建sales
collection:sales
集合:
db.sales.insertMany( [
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-01-01T08:00:00Z") },
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-02-03T09:00:00Z") },
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-03T09:05:00Z") },
{ "_id" : 4, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-02-15T08:00:00Z") },
{ "_id" : 5, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T09:05:00Z") },
{ "_id" : 6, "item" : "xyz", "price" : 5, "quantity" : 5, "date" : ISODate("2014-02-15T12:05:10Z") },
{ "_id" : 7, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-02-15T14:12:12Z") }
] )
Grouping the documents by the 根据item
field, the following operation uses the $first
accumulator to return the first sales date for each item:item
字段对文档进行分组,以下操作使用$first
累加器返回每个物料的第一个销售日期:
db.sales.aggregate(
[
{ $sort: { item: 1, date: 1 } },
{
$group:
{
_id: "$item",
firstSale: { $first: "$date" }
}
}
]
)
The operation returns the following results:该操作返回以下结果:
[
{ _id: 'jkl', firstSale: ISODate("2014-02-03T09:00:00.000Z") },
{ _id: 'xyz', firstSale: ISODate("2014-02-03T09:05:00.000Z") },
{ _id: 'abc', firstSale: ISODate("2014-01-01T08:00:00.000Z") }
]
Missing Data缺少数据
Some documents in the badData
collection are missing fields, other documents are missing values.badData
集合中的一些文档缺少字段,其他文档缺少值。
Create the 创建badData
collection:badData
集合:
db.badData.insertMany( [
{ "_id": 1, "price": 6, "quantity": 6 },
{ "_id": 2, "item": "album", "price": 5 , "quantity": 5 },
{ "_id": 7, "item": "tape", "price": 6, "quantity": 6 },
{ "_id": 8, "price": 5, "quantity": 5 },
{ "_id": 9, "item": "album", "price": 3, "quantity": '' },
{ "_id": 10, "item": "tape", "price": 3, "quantity": 4 },
{ "_id": 12, "item": "cd", "price": 7 }
] )
Query the 查询badData
collection, grouping the output on the item
field:badData
集合,将code>item字段上的输出分组:
db.badData.aggregate( [
{ $sort: { item: 1, price: 1 } },
{ $group:
{
_id: "$item",
inStock: { $first: "$quantity" }
}
}
] )
The $sort
stage orders the documents and passes them to the $group
stage.$sort
阶段对文档进行排序,并将它们传递到$group
阶段。
[
{ _id: null, inStock: 5 },
{ _id: 'album', inStock: '' },
{ _id: 'cd', inStock: null },
{ _id: 'tape', inStock: 4 }
]
$first
selects the first document from each output group:从每个输出组中选择第一个文档:
The包括_id: null
group is included._id:null
组。When the accumulator field,当累加器字段(本例中为$quantity
in this example, is missing,$first
returnsnull
.$quantity
)丢失时,$first
将返回null
。
Use in $setWindowFields
Stage在$setWindowFields
阶段中使用
$setWindowFields
StageNew in version 5.0. 5.0版新增。
Create a 创建一个包含加利福尼亚州(cakeSales
collection that contains cake sales in the states of California (CA
) and Washington (WA
):CA
)和华盛顿州(WA
)蛋糕销售的cakeSales
系列:
db.cakeSales.insertMany( [
{ _id: 0, type: "chocolate", orderDate: new Date("2020-05-18T14:10:30Z"),
state: "CA", price: 13, quantity: 120 },
{ _id: 1, type: "chocolate", orderDate: new Date("2021-03-20T11:30:05Z"),
state: "WA", price: 14, quantity: 140 },
{ _id: 2, type: "vanilla", orderDate: new Date("2021-01-11T06:31:15Z"),
state: "CA", price: 12, quantity: 145 },
{ _id: 3, type: "vanilla", orderDate: new Date("2020-02-08T13:13:23Z"),
state: "WA", price: 13, quantity: 104 },
{ _id: 4, type: "strawberry", orderDate: new Date("2019-05-18T16:09:01Z"),
state: "CA", price: 41, quantity: 162 },
{ _id: 5, type: "strawberry", orderDate: new Date("2019-01-08T06:12:03Z"),
state: "WA", price: 43, quantity: 134 }
] )
This example uses 本例使用$first
in the $setWindowFields
stage to output the first cake sales order type
for each state
:$setWindowFields
阶段中的$first
为每个状态输出第一个蛋糕销售订单类型:
db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: "$state",
sortBy: { orderDate: 1 },
output: {
firstOrderTypeForState: {
$first: "$type",
window: {
documents: [ "unbounded", "current" ]
}
}
}
}
}
] )
In the example:在示例中:
partitionBy: "$state"
partitions the documents in the collection by按state
. There are partitions forCA
andWA
.state
对集合中的文档进行分区。CA
和WA
有分区。sortBy: { orderDate: 1 }
sorts the documents in each partition by按orderDate
in ascending order (1
), so the earliestorderDate
is first.orderDate
按升序(1
)对每个分区中的文档进行排序,因此最早的orderDate
是第一个。
output
sets the将firstOrderTypeForState
field to the first ordertype
from thedocuments
window.firstOrderTypeForState
字段设置为documents
窗口中的第一个订单type
。The该window
contains documents between anunbounded
lower limit and thecurrent
document in the output.window
包含在unbounded
下限和输出中的current
文档之间的文档。This means这意味着$first
returns the first ordertype
for the documents between the beginning of the partition and the current document.$first
返回分区开始和当前文档之间的文档的第一个订单类型。
In this output, the first order 在该输出中,type
value for CA
and WA
is shown in the firstOrderTypeForState
field:CA
和WA
的第一个订单type
值显示在firstOrderTypeForState
字段中:
{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"),
"state" : "CA", "price" : 41, "quantity" : 162, "firstOrderTypeForState" : "strawberry" }
{ "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"),
"state" : "CA", "price" : 13, "quantity" : 120, "firstOrderTypeForState" : "strawberry" }
{ "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"),
"state" : "CA", "price" : 12, "quantity" : 145, "firstOrderTypeForState" : "strawberry" }
{ "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"),
"state" : "WA", "price" : 43, "quantity" : 134, "firstOrderTypeForState" : "strawberry" }
{ "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"),
"state" : "WA", "price" : 13, "quantity" : 104, "firstOrderTypeForState" : "strawberry" }
{ "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"),
"state" : "WA", "price" : 14, "quantity" : 140, "firstOrderTypeForState" : "strawberry" }