Docs Home → Develop Applications → MongoDB Manual
$first (aggregation accumulator)
On this page
Definition
Changed in version 5.0.
Returns the value that results from applying an expression to the first document in a group of documents. Only meaningful when documents are in a defined order.
$first
is available in these stages:
$setWindowFields
(Available starting in MongoDB 5.0)
Note
Disambiguation
This page describes the $first
aggregation accumulator. For
the $first
array operator, see $first
(array operator)
.
Syntax
$first
syntax:
{ $first: <expression> }
For more information on expressions, see Expressions.
Behavior
To define the document order for $first
with the:
$setWindowFields
stage, set the sortBy field.
Note
Although the $sort
stage passes ordered documents as
input to the $group
and $setWindowFields
stages, those stages are not guaranteed to maintain the sort order in
their own output.
When used with $setWindowFields
, $first
returns null
for empty windows. An example empty
window is a { documents: [ -1, -1 ] }
documents window on the first document of a
partition.
Examples
Use in $group
Stage
Consider a sales
collection with the following documents:
{ "_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 compute the first sales date for
each item:
db.sales.aggregate( [ { $sort: { item: 1, date: 1 } }, { $group: { _id: "$item", firstSalesDate: { $first: "$date" } } } ] )
The operation returns the following results:
{ "_id" : "xyz", "firstSalesDate" : ISODate("2014-02-03T09:05:00Z") } { "_id" : "jkl", "firstSalesDate" : ISODate("2014-02-03T09:00:00Z") } { "_id" : "abc", "firstSalesDate" : ISODate("2014-01-01T08:00:00Z") }
Use in $setWindowFields
Stage
New in version 5.0.
Create a cakeSales
collection that contains cake sales in the states
of California (CA
) and Washington (WA
):
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
:
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 bystate
. There are partitions forCA
andWA
.sortBy: { orderDate: 1 }
sorts the documents in each partition byorderDate
in ascending order (1
), so the earliestorderDate
is first.
output
sets thefirstOrderTypeForState
field to the first ordertype
from the documents window.The window contains documents between an
unbounded
lower limit and thecurrent
document in the output. This means$first
returns the first ordertype
for the documents between the beginning of the partition and the current document.
In this output, the first order type
value for CA
and WA
is
shown in the firstOrderTypeForState
field:
{ "_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" }