$push (aggregation)
Definition
$push returns an array of all values that result from
applying an expression to documents.
$push is available in these stages:
$setWindowFields(Available starting in MongoDB 5.0)
Syntax
$push syntax:
{ $push: <expression> }
For more information on expressions, see Expression Operators.
Behavior
When using $push in a $group stage, the order of
the documents coming into the pipeline determines the order of the
documents in the output array. To guarantee a defined order, the
$group pipeline stage should follow a $sort
stage.
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 day and the year of the date field,
the following operation uses the $push accumulator to
compute the list of items and quantities sold for each group:
db.sales.aggregate( [ { $sort: { date: 1, item: 1 } }, { $group: { _id: { day: { $dayOfYear: "$date"}, year: { $year: "$date" } }, itemsSold: { $push: { item: "$item", quantity: "$quantity" } } } } ] )
The operation returns the following results:
{ "_id" : { "day" : 46, "year" : 2014 }, "itemsSold" : [ { "item" : "abc", "quantity" : 10 }, { "item" : "xyz", "quantity" : 10 }, { "item" : "xyz", "quantity" : 5 }, { "item" : "xyz", "quantity" : 10 } ] } { "_id" : { "day" : 34, "year" : 2014 }, "itemsSold" : [ { "item" : "jkl", "quantity" : 1 }, { "item" : "xyz", "quantity" : 5 } ] } { "_id" : { "day" : 1, "year" : 2014 }, "itemsSold" : [ { "item" : "abc", "quantity" : 2 } ] }
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 $push in the $setWindowFields
stage to output an array of cake sales quantity values for each
state:
db.cakeSales.aggregate( [ { $setWindowFields: { partitionBy: "$state", sortBy: { orderDate: 1 }, output: { quantitiesForState: { $push: "$quantity", window: { documents: [ "unbounded", "current" ] } } } } } ] )
In the example:
partitionBy: "$state"partitions the documents in the collection bystate. There are partitions forCAandWA.sortBy: { orderDate: 1 }sorts the documents in each partition byorderDatein ascending order (1), so the earliestorderDateis first.
outputsets the array ofquantityvalues using$pushfor the documents in a documents window.The window contains documents between an
unboundedlower limit and thecurrentdocument in the output. This means$pushappends thequantityvalues to thequantitiesForStatearray for the documents between the beginning of the partition and the current document.
In this output, the array of quantity values for CA and WA
is shown in the quantitiesForState array:
{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"), "state" : "CA", "price" : 41, "quantity" : 162, "quantitiesForState" : [ 162 ] } { "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"), "state" : "CA", "price" : 13, "quantity" : 120, "quantitiesForState" : [ 162, 120 ] } { "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"), "state" : "CA", "price" : 12, "quantity" : 145, "quantitiesForState" : [ 162, 120, 145 ] } { "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"), "state" : "WA", "price" : 43, "quantity" : 134, "quantitiesForState" : [ 134 ] } { "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"), "state" : "WA", "price" : 13, "quantity" : 104, "quantitiesForState" : [ 134, 104 ] } { "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"), "state" : "WA", "price" : 14, "quantity" : 140, "quantitiesForState" : [ 134, 104, 140 ] }