- Reference >
- Database Commands >
- Aggregation Commands >
- group
group¶
On this page
Definition¶
-
group
¶ Deprecated since version 3.4: Mongodb 3.4 deprecates the
group
command. Usedb.collection.aggregate()
with the$group
stage ordb.collection.mapReduce()
instead.Note
Because
group
uses JavaScript, it is subject to a number of performance limitations. For most cases the$group
operator in the aggregation pipeline provides a suitable alternative with fewer restrictions.Groups documents in a collection by the specified key and performs simple aggregation functions, such as computing counts and sums. The command is analogous to a
SELECT <...> GROUP BY
statement in SQL. The command returns a document with the grouped records as well as the command meta-data.The
group
command takes the following prototype form:{ group: { ns: <namespace>, key: <key>, $reduce: <reduce function>, $keyf: <key function>, cond: <query>, finalize: <finalize function> } }
The command accepts a document with the following fields:
Field Type Description ns
string The collection from which to perform the group by operation. key
document The field or fields to group. Returns a “key object” for use as the grouping key. $reduce
function An aggregation function that operates on the documents during the grouping operation. These functions may return a sum or a count. The function takes two arguments: the current document and an aggregation result document for that group. initial
document Initializes the aggregation result document. $keyf
function Optional. Alternative to the key
field. Specifies a function that creates a “key object” for use as the grouping key. Use$keyf
instead ofkey
to group by calculated fields rather than existing document fields.cond
document Optional. The selection criteria to determine which documents in the collection to process. If you omit the cond
field,group
processes all the documents in the collection for the group operation.finalize
function Optional. A function that runs each item in the result set before group
returns the final value. This function can either modify the result document or replace the result document as a whole. Unlike the$keyf
and$reduce
fields that also specify a function, this field name isfinalize
, not$finalize
.For the shell, MongoDB provides a wrapper method
db.collection.group()
. However, thedb.collection.group()
method takes thekeyf
field and thereduce
field whereas thegroup
command takes the$keyf
field and the$reduce
field.
Behavior¶
Limits and Restrictions¶
The group
command does not work with sharded
clusters. Use the aggregation framework or
map-reduce in sharded environments.
The result set must fit within the maximum BSON document size.
Additionally, in version 2.2, the returned array can contain at most
20,000 elements; i.e. at most 20,000 unique groupings. For group by
operations that results in more than 20,000 unique groupings, use
mapReduce
. Previous versions had a limit of 10,000
elements.
Prior to 2.4, the group
command took the mongod
instance’s JavaScript lock which blocked all other JavaScript execution.
mongo
Shell JavaScript Functions/Properties¶
Changed in version 2.4.
In MongoDB 2.4, map-reduce operations
, the
group
command, and $where
operator expressions
cannot access certain global functions or properties, such as
db
, that are available in the mongo
shell.
When upgrading to MongoDB 2.4, you will need to refactor your code if
your map-reduce operations
, group
commands, or $where
operator expressions include any global
shell functions or properties that are no longer available, such as
db
.
The following JavaScript functions and properties are available to
map-reduce operations
, the group
command, and $where
operator expressions in MongoDB 2.4:
Available Properties | Available Functions | |
---|---|---|
args MaxKey MinKey |
assert() BinData() DBPointer() DBRef() doassert() emit() gc() HexData() hex_md5() isNumber() isObject() ISODate() isString() |
Map() MD5() NumberInt() NumberLong() ObjectId() print() printjson() printjsononeline() sleep() Timestamp() tojson() tojsononeline() tojsonObject() UUID() version() |
JavaScript in MongoDB
Although group
uses JavaScript, most
interactions with MongoDB do not use JavaScript but use an
idiomatic driver in the language
of the interacting application.
Examples¶
The following are examples of the db.collection.group()
method.
The examples assume an orders
collection with documents of the
following prototype:
{
_id: ObjectId("5085a95c8fada716c89d0021"),
ord_dt: ISODate("2012-07-01T04:00:00Z"),
ship_dt: ISODate("2012-07-02T04:00:00Z"),
item:
{
sku: "abc123",
price: 1.99,
uom: "pcs",
qty: 25
}
}
Group by Two Fields¶
The following example groups by the ord_dt
and item.sku
fields those documents that have ord_dt
greater than
01/01/2012
:
db.runCommand(
{
group:
{
ns: 'orders',
key: { ord_dt: 1, 'item.sku': 1 },
cond: { ord_dt: { $gt: new Date( '01/01/2012' ) } },
$reduce: function ( curr, result ) { },
initial: { }
}
}
)
The result is a document that contain the retval
field which
contains the group by records, the count
field which contains
the total number of documents grouped, the keys
field which
contains the number of unique groupings (i.e. number of elements
in the retval
), and the ok
field which contains the
command status:
{ "retval" :
[ { "ord_dt" : ISODate("2012-07-01T04:00:00Z"), "item.sku" : "abc123"},
{ "ord_dt" : ISODate("2012-07-01T04:00:00Z"), "item.sku" : "abc456"},
{ "ord_dt" : ISODate("2012-07-01T04:00:00Z"), "item.sku" : "bcd123"},
{ "ord_dt" : ISODate("2012-07-01T04:00:00Z"), "item.sku" : "efg456"},
{ "ord_dt" : ISODate("2012-06-01T04:00:00Z"), "item.sku" : "abc123"},
{ "ord_dt" : ISODate("2012-06-01T04:00:00Z"), "item.sku" : "efg456"},
{ "ord_dt" : ISODate("2012-06-01T04:00:00Z"), "item.sku" : "ijk123"},
{ "ord_dt" : ISODate("2012-05-01T04:00:00Z"), "item.sku" : "abc123"},
{ "ord_dt" : ISODate("2012-05-01T04:00:00Z"), "item.sku" : "abc456"},
{ "ord_dt" : ISODate("2012-06-08T04:00:00Z"), "item.sku" : "abc123"},
{ "ord_dt" : ISODate("2012-06-08T04:00:00Z"), "item.sku" : "abc456"}
],
"count" : 13,
"keys" : 11,
"ok" : 1 }
The method call is analogous to the SQL statement:
SELECT ord_dt, item_sku
FROM orders
WHERE ord_dt > '01/01/2012'
GROUP BY ord_dt, item_sku
Calculate the Sum¶
The following example groups by the ord_dt
and item.sku
fields those documents that have ord_dt
greater than
01/01/2012
and calculates the sum of the qty
field for each
grouping:
db.runCommand(
{ group:
{
ns: 'orders',
key: { ord_dt: 1, 'item.sku': 1 },
cond: { ord_dt: { $gt: new Date( '01/01/2012' ) } },
$reduce: function ( curr, result ) {
result.total += curr.item.qty;
},
initial: { total : 0 }
}
}
)
The retval
field of the returned document is an array of
documents that contain the group by fields and the calculated
aggregation field:
{ "retval" :
[ { "ord_dt" : ISODate("2012-07-01T04:00:00Z"), "item.sku" : "abc123", "total" : 25 },
{ "ord_dt" : ISODate("2012-07-01T04:00:00Z"), "item.sku" : "abc456", "total" : 25 },
{ "ord_dt" : ISODate("2012-07-01T04:00:00Z"), "item.sku" : "bcd123", "total" : 10 },
{ "ord_dt" : ISODate("2012-07-01T04:00:00Z"), "item.sku" : "efg456", "total" : 10 },
{ "ord_dt" : ISODate("2012-06-01T04:00:00Z"), "item.sku" : "abc123", "total" : 25 },
{ "ord_dt" : ISODate("2012-06-01T04:00:00Z"), "item.sku" : "efg456", "total" : 15 },
{ "ord_dt" : ISODate("2012-06-01T04:00:00Z"), "item.sku" : "ijk123", "total" : 20 },
{ "ord_dt" : ISODate("2012-05-01T04:00:00Z"), "item.sku" : "abc123", "total" : 45 },
{ "ord_dt" : ISODate("2012-05-01T04:00:00Z"), "item.sku" : "abc456", "total" : 25 },
{ "ord_dt" : ISODate("2012-06-08T04:00:00Z"), "item.sku" : "abc123", "total" : 25 },
{ "ord_dt" : ISODate("2012-06-08T04:00:00Z"), "item.sku" : "abc456", "total" : 25 }
],
"count" : 13,
"keys" : 11,
"ok" : 1 }
The method call is analogous to the SQL statement:
SELECT ord_dt, item_sku, SUM(item_qty) as total
FROM orders
WHERE ord_dt > '01/01/2012'
GROUP BY ord_dt, item_sku
Calculate Sum, Count, and Average¶
The following example groups by the calculated day_of_week
field,
those documents that have ord_dt
greater than 01/01/2012
and
calculates the sum, count, and average of the qty
field for each
grouping:
db.runCommand(
{
group:
{
ns: 'orders',
$keyf: function(doc) {
return { day_of_week: doc.ord_dt.getDay() };
},
cond: { ord_dt: { $gt: new Date( '01/01/2012' ) } },
$reduce: function( curr, result ) {
result.total += curr.item.qty;
result.count++;
},
initial: { total : 0, count: 0 },
finalize: function(result) {
var weekdays = [
"Sunday", "Monday", "Tuesday",
"Wednesday", "Thursday",
"Friday", "Saturday"
];
result.day_of_week = weekdays[result.day_of_week];
result.avg = Math.round(result.total / result.count);
}
}
}
)
The retval
field of the returned document is an array of
documents that contain the group by fields and the calculated
aggregation field:
{
"retval" :
[
{ "day_of_week" : "Sunday", "total" : 70, "count" : 4, "avg" : 18 },
{ "day_of_week" : "Friday", "total" : 110, "count" : 6, "avg" : 18 },
{ "day_of_week" : "Tuesday", "total" : 70, "count" : 3, "avg" : 23 }
],
"count" : 13,
"keys" : 3,
"ok" : 1
}
See also