difference between $first $min accumulator ?

244 views
Skip to first unread message

Ted Chyn

unread,
Oct 2, 2014, 6:23:24 PM10/2/14
to mongod...@googlegroups.com
following example using $min and $first after $group produce exactly identical result. can any one tells me the difference between these accumulator during aggregation ? tyvm




test@-Mongo-> db.sales.find()
{ "_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") }
test@-Mongo-> db.sales.aggregate(
...    [
...      { $sort: { item: 1, date: 1 } },
...      {
...        $group:
...          {
...            _id: "$item",
...            firstSalesDate: { $first: "$date" }
...          }
...      }
...    ]
... )
{ "_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") }
test@-Mongo-> db.sales.aggregate(
...    [
...      { $sort: { item: 1, date: 1 } },
...      {
...        $group:
...          {
...            _id: "$item",
...            firstSalesDate: { $min: "$date" }
...          }
...      }
...    ]
... )
{ "_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") }

Will Berkeley

unread,
Oct 3, 2014, 10:37:36 AM10/3/14
to mongod...@googlegroups.com
The $first operator returns the value of its expression argument computed from the first document in the $group. So, each time a new _id is encountered in the course of executing the $group, the value of $first is computed from the first document to go into the group. The order in which documents are grouped is well-defined only if a $sort has ordered the documents, and in that case $first gives you the value of its expression as computed on the document that is sorted first in the specified order. This means it can behave like $min or $max when grouping and sorting on the same fields, but is also unlike $min or $max when being used on a field that is not one of the fields used to define the order. 

Actually, the most common use of $first I see is without an order defined. It's useful in the case of grouping on the documents produced from unwinding an array field in a single document, where one wants to keep fields from the original document. In this case, you can use $first to project them into each group.

-Will

Ted Chyn

unread,
Oct 7, 2014, 1:13:26 PM10/7/14
to mongod...@googlegroups.com
thanks for reply,

$first $last require sort and I am not sure whether $max $min require sort or not.

do $max $min require sort behind the scene ? if not how are these 2 operator $max $min work behind the scene ?

tyvm in advance

--
You received this message because you are subscribed to the Google Groups "mongodb-user"
group.
 
For other MongoDB technical support options, see: http://www.mongodb.org/about/support/.
---
You received this message because you are subscribed to a topic in the Google Groups "mongodb-user" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mongodb-user/WL6q-BRejeo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mongodb-user...@googlegroups.com.
To post to this group, send email to mongod...@googlegroups.com.
Visit this group at http://groups.google.com/group/mongodb-user.
To view this discussion on the web visit https://groups.google.com/d/msgid/mongodb-user/9e7022e8-bd7f-4cd1-8a01-b41ff5c176fb%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Will Berkeley

unread,
Oct 7, 2014, 4:26:14 PM10/7/14
to mongod...@googlegroups.com
$min and $max don't require a sort. Technically, $first and $last don't either, it's just that the first and last value seen in making a group are pretty meaningless without an order on the documents as they are grouped. $min and $max, behind the scenes, will just record a maximum (minimum) value seen so far for each group and, when a new document enters the group, the maximum (minimum) value is updated if necessary.

-Will

You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongodb-user...@googlegroups.com.

To post to this group, send email to mongod...@googlegroups.com.
Visit this group at http://groups.google.com/group/mongodb-user.

Ted Chyn

unread,
Oct 7, 2014, 9:42:28 PM10/7/14
to mongod...@googlegroups.com
i think i got this figure out

$max = $sort and $first or $last depending on sorting asc or desc see below
==

use $max without sort
test@-Mongo-> db.zip1.aggregate([{$group:{_id:"$state", pop: {$max:"$pop"}} }])
{ "_id" : "WV", "pop" : 70185 }   

use $last with sort asc
test@-Mongo-> db.zip1.aggregate([{$sort:{state:1,pop:1}},{$group:{_id:"$state", pop: {$last:"$pop"}} }])
{ "_id" : "WV", "pop" : 70185 }

### notice when use $last without sort - you will get the last records in the aggregation $natural order ###


test@-Mongo-> db.zip1.aggregate([{$group:{_id:"$state", pop: {$last:"$pop"}} }])
{ "_id" : "WV", "pop" : 233 }


Reply all
Reply to author
Forward
0 new messages