diff --git a/source/aggregation.txt b/source/aggregation.txt index 2c5ca44df57..deaf3d80a54 100644 --- a/source/aggregation.txt +++ b/source/aggregation.txt @@ -4,19 +4,39 @@ Aggregation =========== -Aggregation provides -a natural method for aggregating data inside of MongoDB. +.. default-domain:: mongodb + +Aggregation provides a natural method for aggregating data inside of +MongoDB. For a description of MongoDB aggregation, see -:doc:`/applications/aggregation`. For examples of aggregation, see -:doc:`/tutorial/aggregation-examples`. For descriptions of aggregation -operators, see :doc:`/reference/aggregation`. +:doc:`/applications/aggregation`: + +.. toctree:: + :maxdepth: 2 + + applications/aggregation -The following is the outline of the aggregation documentation: +For examples of aggregation, see +:doc:`/tutorial/aggregation-examples`: .. toctree:: :maxdepth: 3 - applications/aggregation tutorial/aggregation-examples + +For the descriptions of aggregation operators, see +:doc:`/reference/aggregation`. + +.. toctree:: + :maxdepth: 3 + reference/aggregation + +In addition to the aggregation framework, MongoDB provides simple +:doc:`aggregation methods and commands `: + +.. toctree:: + :maxdepth: 2 + + reference/simple-aggregation diff --git a/source/applications/aggregation.txt b/source/applications/aggregation.txt index 9cbc99491c2..cea2c3ad093 100644 --- a/source/applications/aggregation.txt +++ b/source/applications/aggregation.txt @@ -50,7 +50,7 @@ In a shell environment the pipe redirects a stream of characters from the output of one process to the input of the next. The MongoDB aggregation pipeline streams MongoDB documents from one :ref:`pipeline operator ` to the next to process the -documents. +documents. Pipeline operators can be repeated in the pipe. All pipeline operators process a stream of documents and the pipeline behaves as if the operation scans a :term:`collection` and diff --git a/source/reference/command/count.txt b/source/reference/command/count.txt index 2ad7ba8e00b..6b1cd1632a7 100644 --- a/source/reference/command/count.txt +++ b/source/reference/command/count.txt @@ -7,25 +7,85 @@ count .. dbcommand:: count The :dbcommand:`count` command counts the number of documents in a - collection. For example: - + collection. The command returns a document that contains the count + as well as the command status. The :dbcommand:`count` command takes + the following prototype form: + .. code-block:: javascript + + { count: , query: , limit: , skip: } + + The command fields are as follows: + + :field String count: + + The name of the collection to count. + + :field document query: + + Optional. Specifies the selection query to determine which + documents in the collection to count. + + :field integer limit: + + Optional. Specifies the limit for the documents matching the + selection ``query``. + + :field integer skip: + Optional. Specifies the number of matching documents to skip. - > db.runCommand( { count: "collection" } ); - { "n" : 10 , "ok" : 1 } + Consider the following examples of the :dbcommand:`count` command: - In the :program:`mongo` shell, this returns the number of documents - in the collection (e.g. ``collection``.) You may also use the - :method:`count() ` method on any cursor object to - return a count of the number of documents in that cursor. The - following operation produces the same result in the - :program:`mongo` shell: + - Count the number of all documents in the ``orders`` collection: - .. code-block:: javascript + .. code-block:: javascript + + db.runCommand( { count: 'orders' } ) + + In the result, the ``n``, which represents the count, is ``26`` + and the command status ``ok`` is ``1``: + + .. code-block:: javascript + + { "n" : 26, "ok" : 1 } + + - Count the number of the documents in the ``orders`` collection + with the field ``ord_dt`` greater than ``new Date('01/01/2012')``: + + .. code-block:: javascript + + db.runCommand( { count:'orders', + query: { ord_dt: { $gt: new Date('01/01/2012') } } + } ) + + In the result, the ``n``, which represents the count, is ``13`` + and the command status ``ok`` is ``1``: + + .. code-block:: javascript + + { "n" : 13, "ok" : 1 } + + - Count the number of the documents in the ``orders`` collection + with the field ``ord_dt`` greater than ``new Date('01/01/2012')`` + skipping the first ``10`` matching records: + + .. code-block:: javascript + + db.runCommand( { count:'orders', + query: { ord_dt: { $gt: new Date('01/01/2012') } }, + skip: 10 } ) + + In the result, the ``n``, which represents the count, is ``3`` and + the command status ``ok`` is ``1``: + + .. code-block:: javascript - > db.collection.count(): - { "n" : 10 , "ok" : 1 } + { "n" : 3, "ok" : 1 } - The collection in this example has 10 documents. + .. note:: + + MongoDB also provides the :method:`cursor.count()` + method and the shell wrapper :method:`db.collection.count()` + method. .. read-lock diff --git a/source/reference/command/distinct.txt b/source/reference/command/distinct.txt index 723ce6e5c9d..cf1af8c89a6 100644 --- a/source/reference/command/distinct.txt +++ b/source/reference/command/distinct.txt @@ -6,28 +6,68 @@ distinct .. dbcommand:: distinct - The :dbcommand:`distinct` command returns an array of distinct values for a - given field across a single collection. The command takes the - following form: + The :dbcommand:`distinct` command finds the distinct values for a + specified field across a single collection. The command returns a + document that contains an array of the distinct values as well as + the query plan and status. The command takes the following prototype + form: .. code-block:: javascript - { distinct: collection, key: age, query: { query: { field: { $exists: true } } } } + { distinct: collection, key: , query: } - This operation returns all distinct values of the field (or - ``key``) ``age`` in documents that match the query ``{ field: { - $exists: true }``. + The command fields are as follows: + + :field String collection: + + The name of the collection to query for distinct values. - .. note:: + :field string field: + + Specifies the field for which to return the distinct values. + + :field document query: + + Optional. Specifies the selection ``query`` to determine the + subset of documents from which to retrieve the distinct + values. - The query portion of the :dbcommand:`distinct` is optional. + Consider the following examples of the :dbcommand:`distinct` command: - The shell and many :term:`drivers ` provide a helper method that provides - this functionality. You may prefer the following equivalent syntax: + - Return an array of the distinct values of the field ``ord_dt`` + from all documents in the ``orders`` collection: - .. code-block:: javascript + .. code-block:: javascript + + db.runCommand ( { distinct: 'orders', key: 'ord_dt' } ) + + - Return an array of the distinct values of the field ``sku`` in the + subdocument ``item`` from all documents in the ``orders`` + collection: + + .. code-block:: javascript - db.collection.distinct("age", { field: { $exists: true } } ); + db.runCommand ( { distinct: 'orders', key: 'item.sku' } ) - The :dbcommand:`distinct` command will use an index to locate and - return data. + - Return an array of the distinct values of the field ``ord_dt`` + from the documents in the ``orders`` collection where the + ``price`` is greater than ``10``: + + .. code-block:: javascript + + db.runCommand ( { distinct: 'orders', + key: 'ord_dt', + query: { price: { $gt: 10 } } + } ) + + .. note:: + + - MongoDB also provides the shell wrapper method + :method:`db.collection.distinct()` for the + :dbcommand:`distinct` command. Additionally, many MongoDB + :term:`drivers ` also provide a wrapper method. Refer + to the specific driver documentation. + + - When possible, the :dbcommand:`distinct` command will use an + index to find the documents in the query as well as to return + the data. diff --git a/source/reference/command/group.txt b/source/reference/command/group.txt index 186acf12646..6f05ac3660d 100644 --- a/source/reference/command/group.txt +++ b/source/reference/command/group.txt @@ -5,85 +5,262 @@ group .. default-domain:: mongodb .. dbcommand:: group + + The :dbcommand:`group` command 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 :dbcommand:`group` command takes the following prototype + form: + + .. code-block:: none + + { group: { ns: , + key: , + $reduce: , + $keyf: , + cond: , + finalize: } } - The :dbcommand:`group` command returns an array of grouped items. :dbcommand:`group` - provides functionality analogous to the ``GROUP BY`` statement in - SQL. Consider the following example: + The command fields are as follows: - .. code-block:: javascript + :field ns: + + Specifies the collection from which to perform the group by + operation. - db.users.runCommand( { group: - { key: { school_id: true }, - cond: { active: 1 }, - reduce: function(obj, prev) { obj.total += 1; }, - initial: { total: 0 } - } } ); + :field key: Specifies one or more document fields to group. Returns + a "key object" for use as the grouping key. - More typically, in the :program:`mongo` shell, you will call the - :dbcommand:`group` command using the :method:`group()` - method. Consider the following form: + :field $reduce: Specifies an aggregation function that operates on + the documents during the grouping operation, such as + compute a sum or a count. The aggregation function + takes two arguments: the current document and an + aggregation result document for that group. - .. code-block:: javascript + :field initial: Initializes the aggregation result document. - db.users.group( { key: { school_id: true }, - cond: { active: 1 }, - reduce: function(obj, prev) { obj.total += 1; }, - initial: { total: 0 } - } ); - - In these examples :dbcommand:`group` runs against the collection - ``users`` and counts the total number of active users from each - school. Fields allowed by the group command include: - - :field document key: Specify one or more fields to group by. Use the - form of a :term:`document`. - - :field reduce: Specify a reduce function that operates over all the - iterated objects. Typically these aggregator - functions perform some sort of summing or - counting. The reduce function takes two arguments: - the current document and an aggregation counter - object. - - :field initial: The starting value of the aggregation counter - object. - - :field keyf: Optional. A function that returns a "key - object" for use as the grouping key. Use - ``keyf`` instead of ``key`` to specify a key - that is not a single/multiple existing - fields. For example, use ``keyf`` to group by - day or week in place of a fixed ``key``. - - :field cond: Optional. A statement that must evaluate to true for - the :method:`db.collection.group()` to process this - document. Essentially this argument specifies - a query document (as for - :method:`db.collection.find()`). Unless specified, - :method:`db.collection.group()` runs the "reduce" function - against all documents in the collection. - - :field finalize: Optional. A function that runs each item - in the result set before - :method:`db.collection.group()` returns the final - value. This function can either modify - the document by computing and adding an - average field, or return compute and - return a new document. + :field $keyf: Optional. Alternative to the ``key`` field. Specifies a + function that creates a "key object" for + use as the grouping key. Use the ``keyf`` instead of + ``key`` to group by calculated fields rather than + existing document fields. - .. note:: + :field cond: Optional. Specifies the selection criteria to determine + which documents in the collection to process. If the + ``cond`` field is omitted, the + :method:`db.collection.group()` processes all the + documents in the collection for the group operation. - The result set of the :method:`db.collection.group()` must fit - within the size :ref:`maximum BSON document - `. Furthermore, you must ensure that - there are fewer then 10,000 unique keys. If you have more than - this, use :dbcommand:`mapReduce`. + :field finalize: Optional. Specifies a function that runs each item + in the result set before :method:`db.collection.group()` + returns the final value. This function + can either modify the result document or + replace the result document as a whole. + + .. note:: + + Unlike the ``$keyf`` and the ``$reduce`` fields + that specify a function, the field name is + ``finalize`` and not ``$finalize``. .. warning:: - :method:`group()` does not work in :term:`shard environments - `. Use the :term:`aggregation framework` or - :term:`map-reduce` (i.e. :command:`mapReduce` in :term:`sharded - environments `. + - The :dbcommand:`group` command does not work with + :term:`sharded clusters `. Use the + :term:`aggregation framework` or :term:`map-reduce` in + :term:`sharded environments `. + + - The :dbcommand:`group` command takes a read lock and does not + allow any other threads to execute JavaScript while it is + running. + + .. note:: + + The result set must fit within the :ref:`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 + :dbcommand:`mapReduce`. Previous versions had a limit of 10,000 + elements. + + For the shell, MongoDB provides a wrapper method + :method:`db.collection.group()`; however, the + :method:`db.collection.group()` method takes the ``keyf`` field and + the ``reduce`` field whereas the :dbcommand:`group` command takes + the ``$keyf`` field and the ``$reduce`` field. + + Consider the following examples of the :method:`db.collection.group()` method: + + The examples assume an ``orders`` collection with documents of the + following prototype: + + .. code-block:: javascript + + { + _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 } + } + + - The following example groups by the ``ord_dt`` and ``item.sku`` + fields those documents that have ``ord_dt`` greater than + ``01/01/2012``: + + .. code-block:: javascript + + 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 documents 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: + + .. code-block:: javascript + + { "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: + + .. code-block:: sql + + SELECT ord_dt, item_sku + FROM orders + WHERE ord_dt > '01/01/2012' + GROUP BY ord_dt, item_sku + + - 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: + + .. code-block:: javascript + + 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: + + .. code-block:: javascript + + { "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: + + .. code-block:: sql + + SELECT ord_dt, item_sku, SUM(item_qty) as total + FROM orders + WHERE ord_dt > '01/01/2012' + GROUP BY ord_dt, item_sku + + + - 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: + + .. code-block:: javascript + + 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: + + .. code-block:: javascript + + { "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 } + .. seealso:: :doc:`/applications/aggregation` + .. read-lock diff --git a/source/reference/method/cursor.count.txt b/source/reference/method/cursor.count.txt index 6595fd65d1a..9018a4dd997 100644 --- a/source/reference/method/cursor.count.txt +++ b/source/reference/method/cursor.count.txt @@ -6,16 +6,59 @@ cursor.count() .. method:: cursor.count() - :param boolean override: Override the effects of the - :method:`cursor.skip()` and :method:`cursor.limit()` - methods on the cursor. + The :method:`count() ` method counts the number of + documents referenced by a cursor. Append the :method:`count() + ` method to a :method:`find() + ` query to return the number of matching + documents, as in the following prototype: - Append the :method:`count() ` method on a - ":method:`find() `" query to return the number - of matching objects for any query. + .. code-block:: javascript - In normal operation, :method:`cursor.count()` ignores the effects of the - :method:`cursor.skip()` and :method:`cursor.limit()`. To consider these - effects specify ":method:`count(true) `". + db.collection.find().count() - .. seealso:: :method:`cursor.size()`. + This operation does not actually perform the :method:`find() + `; instead, the operation counts the results + that would be returned by the :method:`find() + `. + + The :method:`count() ` can accept the following argument: + + :param boolean applySkipLimit: + + Optional. Specifies whether to consider the effects of the + :method:`cursor.skip()` and :method:`cursor.limit()` methods + in the count. By default, the :method:`count() + ` method ignores the effects of the + :method:`cursor.skip()` and :method:`cursor.limit()`. Set + ``applySkipLimit`` to ``true`` to consider the effect of + these methods. + + .. seealso:: :method:`cursor.size()` + + MongoDB also provides the shell wrapper + :method:`db.collection.count()` for the + ``db.collection.find().count()`` construct. + + Consider the following examples of the :method:`count() + ` method: + + - Count the number of all documents in the ``orders`` collection: + + .. code-block:: javascript + + db.orders.find().count() + + - Count the number of the documents in the ``orders`` collection + with the field ``ord_dt`` greater than ``new Date('01/01/2012')``: + + .. code-block:: javascript + + db.orders.find( { ord_dt: { $gt: new Date('01/01/2012') } } ).count() + + - Count the number of the documents in the ``orders`` collection + with the field ``ord_dt`` greater than ``new Date('01/01/2012')`` + *taking into account* the effect of the ``limit(5)``: + + .. code-block:: javascript + + db.orders.find( { ord_dt: { $gt: new Date('01/01/2012') } } ).limit(5).count(true) diff --git a/source/reference/method/db.collection.count.txt b/source/reference/method/db.collection.count.txt new file mode 100644 index 00000000000..98b7cbf43ab --- /dev/null +++ b/source/reference/method/db.collection.count.txt @@ -0,0 +1,54 @@ +===================== +db.collection.count() +===================== + +.. default-domain:: mongodb + +.. method:: db.collection.count( ) + + The :method:`db.collection.count()` method is a shell wrapper that + returns the count of documents that would match a :method:`find() + ` query; i.e., :method:`db.collection.count()` + method is equivalent to: + + .. code-block:: javascript + + db.collection.find().count(); + + This operation does not actually perform the :method:`find() + `; instead, the operation counts the results + that would be returned by the :method:`find() + `. + + The :method:`db.collection.count()` method can accept the following argument: + + :param document query: Specifies the selection query criteria. + + Consider the following examples of the :method:`db.collection.count()` method + + - Count the number of all documents in the ``orders`` collection: + + .. code-block:: javascript + + db.orders.count() + + The query is equivalent to the following: + + .. code-block:: javascript + + db.orders.find().count() + + - Count the number of the documents in the ``orders`` collection + with the field ``ord_dt`` greater than ``new Date('01/01/2012')``: + + .. code-block:: javascript + + db.orders.count( { ord_dt: { $gt: new Date('01/01/2012') } } ) + + The query is equivalent to the following: + + .. code-block:: javascript + + db.orders.find( { ord_dt: { $gt: new Date('01/01/2012') } } ).count() + +.. seealso:: :method:`cursor.count()` \ No newline at end of file diff --git a/source/reference/method/db.collection.distinct.txt b/source/reference/method/db.collection.distinct.txt index 533f9484319..4a9ba7e5140 100644 --- a/source/reference/method/db.collection.distinct.txt +++ b/source/reference/method/db.collection.distinct.txt @@ -4,16 +4,56 @@ db.collection.distinct() .. default-domain:: mongodb -.. method:: db.collection.distinct(field) +.. method:: db.collection.distinct() - :param field string: A field that exists in a document or documents - within the :term:`collection`. - - Returns an array that contains a list of the distinct values for - the specified field. + The :method:`db.collection.distinct()` method finds the distinct + values for a specified field across a single collection and returns + the results in an array. The method accepts the following argument: + + :param string field: + + Specifies the field for which to return the distinct values. + + :param document query: + + Specifies the selection ``query`` to determine the subset of + documents from which to retrieve the distinct values. .. note:: - The :method:`db.collection.distinct()` method provides a wrapper around the - :dbcommand:`distinct`. Results must not be larger than the maximum - :ref:`BSON size `. + - The :method:`db.collection.distinct()` method provides a + wrapper around the :dbcommand:`distinct` command. Results must + not be larger than the maximum :ref:`BSON size + `. + + - When possible to use covered indexes, the + :method:`db.collection.distinct()` method will use an index to + find the documents in the query as well as to return the data. + + Consider the following examples of the + :method:`db.collection.distinct()` method: + + - Return an array of the distinct values of the field ``ord_dt`` + from all documents in the ``orders`` collection: + + .. code-block:: javascript + + db.orders.distinct( 'ord_dt' ) + + - Return an array of the distinct values of the field ``sku`` in the + subdocument ``item`` from all documents in the ``orders`` + collection: + + .. code-block:: javascript + + db.orders.distinct( 'item.sku' ) + + - Return an array of the distinct values of the field ``ord_dt`` + from the documents in the ``orders`` collection where the + ``price`` is greater than ``10``: + + .. code-block:: javascript + + db.orders.distinct( 'ord_dt', + { price: { $gt: 10 } } + ) diff --git a/source/reference/method/db.collection.group.txt b/source/reference/method/db.collection.group.txt index 7cd8bc2783c..1a182d45263 100644 --- a/source/reference/method/db.collection.group.txt +++ b/source/reference/method/db.collection.group.txt @@ -4,87 +4,207 @@ db.collection.group() .. default-domain:: mongodb -.. method:: db.collection.group({key, reduce, initial, [keyf,] [cond,] finalize}) +.. method:: db.collection.group( { key, reduce, initial, [keyf,] [cond,] finalize } ) + + The :method:`db.collection.group()` method groups documents in a + collection by the specified keys and performs simple aggregation + functions such as computing counts and sums. The method is analogous + to a ``SELECT .. GROUP BY`` statement in SQL. The :method:`group() + ` method returns an array. The :method:`db.collection.group()` accepts a single :term:`document` that contains the following: - :field key: Specifies one or more fields to group by. - - :field reduce: Specifies a reduce function that operates over all the - iterated objects. Typically these aggregator - functions perform some sort of summing or - counting. The reduce function takes two arguments: - the current document and an aggregation counter - object. - - :field initial: The starting value of the aggregation counter - object. - - :field keyf: Optional. An optional function that returns a "key - object" for use as the grouping key. Use - ``keyf`` instead of ``key`` to specify a key - that is not a single/multiple existing - fields. For example, use ``keyf`` to group by - day or week in place of a fixed ``key``. - - :field cond: Optional. A statement that must evaluate to true for - the :method:`db.collection.group()` to process this - document. Simply, this argument specifies - a query document (as for - :method:`db.collection.find()`). Unless specified, - :method:`db.collection.group()` runs the "reduce" function - against all documents in the collection. - - :field finalize: Optional. A function that runs each item - in the result set before :method:`db.collection.group()` - returns the final value. This function - can either modify the document by - computing and adding an average field, or - return compute and return a new document. - - .. warning:: - - :method:`db.collection.group()` does not work in :term:`shard environments - `. Use the :term:`aggregation framework` or - :term:`map-reduce` in :term:`sharded environments `. - - .. note:: - - The result set of the :method:`db.collection.group()` must fit within a - single :term:`BSON` object. + :field key: Specifies one or more document fields to group by. - Furthermore, you must ensure that there are fewer then 10,000 - unique keys. If you have more than this, use - :dbcommand:`mapReduce`. + :field reduce: Specifies an aggregation function that operates on + the documents during the grouping operation, such as + compute a sum or a count. The aggregation function + takes two arguments: the current document and an + aggregation result document for that group. - :method:`db.collection.group()` provides a simple aggregation capability similar - to the function of ``GROUP BY`` in SQL statements. Use - :method:`db.collection.group()` to return counts and averages from collections - of MongoDB documents. Consider the following example - :method:`db.collection.group()` command: + :field initial: Initializes the aggregation result document. - .. code-block:: javascript + :field keyf: Optional. Alternative to the ``key`` field. Specifies a + function that creates a "key object" for use as the + grouping key. Use the ``keyf`` instead of ``key`` to + group by calculated fields rather than existing + document fields. - db.collection.group( - {key: { a:true, b:true }, - cond: { active: 1 }, - reduce: function(obj,prev) { prev.csum += obj.c; }, - initial: { csum: 0 } - }); + :field cond: Optional. Specifies the selection criteria to determine + which documents in the collection to process. If the + ``cond`` field is omitted, the + :method:`db.collection.group()` processes all the + documents in the collection for the group operation. - This command in the :program:`mongo` shell groups the documents in - the collection where the field ``active`` equals ``1`` into sets - for all combinations of combinations values of the ``a`` and ``b`` - fields. Then, within each group, the reduce function adds up each document's - c field into the csum field in the aggregation counter document. This is - equivalent to the following SQL statement. - - .. code-block:: sql + :field finalize: Optional. Specifies a function that runs each item + in the result set before :method:`db.collection.group()` + returns the final value. This function + can either modify the result document or + replace the result document as a whole. + + The :method:`db.collection.group()` method is a shell wrapper for + the :dbcommand:`group` command; however, the + :method:`db.collection.group()` method takes the ``keyf`` field and + the ``reduce`` field whereas the :dbcommand:`group` command takes + the ``$keyf`` field and the ``$reduce`` field. + + .. warning:: - SELECT a,b,sum(c) csum FROM collection WHERE active=1 GROUP BY a,b + - The :method:`db.collection.group()` method does not work with + :term:`sharded clusters `. Use the + :term:`aggregation framework` or :term:`map-reduce` in + :term:`sharded environments `. - .. seealso:: The ":wiki:`Aggregation`" wiki page and - ":doc:`/applications/aggregation`." + - The :dbcommand:`group` command takes a read lock and does not + allow any other threads to execute JavaScript while it is + running. - .. STUB ":doc:`/applications/simple-aggregation`" + .. note:: + + - The result set must fit within the :ref:`maximum BSON document + size `. + + - 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 :dbcommand:`mapReduce`. Previous versions had a limit of + 10,000 elements. + +Consider the following examples of the :method:`db.collection.group()` method: + +The examples assume an ``orders`` collection with documents of the +following prototype: + +.. code-block:: javascript + + { + _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 } + } + +- The following example groups by the ``ord_dt`` and ``item.sku`` + fields those documents that have ``ord_dt`` greater than + ``01/01/2011``: + + .. code-block:: javascript + + db.orders.group( { + key: { ord_dt: 1, 'item.sku': 1 }, + cond: { ord_dt: { $gt: new Date( '01/01/2012' ) } }, + reduce: function ( curr, result ) { }, + initial: { } + } ) + + The result is an array of documents that contain the group by fields: + + .. code-block:: javascript + + [ { "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"} ] + + The method call is analogous to the SQL statement: + + .. code-block:: sql + + SELECT ord_dt, item_sku + FROM orders + WHERE ord_dt > '01/01/2012' + GROUP BY ord_dt, item_sku + +- The following example groups by the ``ord_dt`` and ``item.sku`` + fields, those documents that have ``ord_dt`` greater than + ``01/01/2011`` and calculates the sum of the ``qty`` field for each + grouping: + + .. code-block:: javascript + + db.orders.group( { + 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 result is an array of documents that contain the group by fields + and the calculated aggregation field: + + .. code-block:: javascript + + [ { "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 } ] + + The method call is analogous to the SQL statement: + + .. code-block:: sql + + SELECT ord_dt, item_sku, SUM(item_qty) as total + FROM orders + WHERE ord_dt > '01/01/2012' + GROUP BY ord_dt, item_sku + + +- The following example groups by the calculated ``day_of_week`` field, + those documents that have ``ord_dt`` greater than ``01/01/2011`` and + calculates the sum, count, and average of the ``qty`` field for each + grouping: + + .. code-block:: javascript + + db.orders.group( { + 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 result is an array of documents that contain the group by fields + and the calculated aggregation field: + + .. code-block:: javascript + + [ { "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 } ] + + .. seealso:: :doc:`/applications/aggregation` + + .. STUB ":doc:`/applications/simple-aggregation`" diff --git a/source/reference/simple-aggregation.txt b/source/reference/simple-aggregation.txt new file mode 100644 index 00000000000..c680d277b87 --- /dev/null +++ b/source/reference/simple-aggregation.txt @@ -0,0 +1,41 @@ +======================================= +Simple Aggregation Methods and Commands +======================================= + +.. default-domain:: mongodb + +In addition to the :doc:`aggregation +framework` and :term:`map-reduce`, MongoDB +provides the following methods and commands to perform aggregation: + +Count +----- + +MongoDB offers the following command and methods to provide ``count`` +functionality: + +- :doc:`/reference/command/count` + +- :doc:`/reference/method/db.collection.count` + +- :doc:`/reference/method/cursor.count` + +Distinct +-------- + +MongoDB offers the following command and method to provide the +``distinct`` functionality: + +- :doc:`/reference/command/distinct` + +- :doc:`/reference/method/db.collection.distinct` + +Group +----- + +MongoDB offers the following command and method to provide ``group`` +functionality: + +- :doc:`/reference/command/group` + +- :doc:`/reference/method/db.collection.group`