<commit_before>Map/Reduce Example
==================

.. testsetup::

  from pymongo import Connection
  connection = Connection()
  connection.drop_database('map_reduce_example')

This example shows how to use the
:meth:`~pymongo.collection.Collection.map_reduce` method to perform
map/reduce style aggregations on your data.

.. note::

    Map/Reduce requires server version **>= 1.1.1**. The PyMongo
    :meth:`~pymongo.collection.Collection.map_reduce` helper requires
    PyMongo version **>= 1.2**.

Setup
-----
To start, we'll insert some example data which we can perform
map/reduce queries on:

.. doctest::

  >>> from pymongo import Connection
  >>> db = Connection().map_reduce_example
  >>> db.things.insert({"x": 1, "tags": ["dog", "cat"]})
  ObjectId('...')
  >>> db.things.insert({"x": 2, "tags": ["cat"]})
  ObjectId('...')
  >>> db.things.insert({"x": 3, "tags": ["mouse", "cat", "dog"]})
  ObjectId('...')
  >>> db.things.insert({"x": 4, "tags": []})
  ObjectId('...')

Basic Map/Reduce
----------------
Now we'll define our **map** and **reduce** functions. In this case
we're performing the same operation as in the `MongoDB Map/Reduce
documentation <http://www.mongodb.org/display/DOCS/MapReduce>`_ -
counting the number of occurrences for each tag in the ``tags`` array,
across the entire collection.

Our **map** function just emits a single `(key, 1)` pair for each tag in
the array:

.. doctest::

  >>> from bson.code import Code
  >>> mapper = Code("function () {"
  ...            "  this.tags.forEach(function(z) {"
  ...            "    emit(z, 1);"
  ...            "  });"
  ...            "}")

The **reduce** function sums over all of the emitted values for a given key:

.. doctest::

  >>> reducer = Code("function (key, values) {"
  ...               "  var total = 0;"
  ...               "  for (var i = 0; i < values.length; i++) {"
  ...               "    total += values[i];"
  ...               "  }"
  ...               "  return total;"
  ...               "}")

.. note:: We can't just return ``values.length`` as the **reduce** function
   might be called iteratively on the results of other reduce steps.

Finally, we call :meth:`~pymongo.collection.Collection.map_reduce` and
iterate over the result collection:

.. doctest::

  >>> result = db.things.map_reduce(mapper, reduce, "myresults")
  >>> for doc in result.find():
  ...   print doc
  ...
  {u'_id': u'cat', u'value': 3.0}
  {u'_id': u'dog', u'value': 2.0}<commit_msg>Improve legibility of map/reduce code examples<commit_after>Map/Reduce Example
==================

.. testsetup::

  from pymongo import Connection
  connection = Connection()
  connection.drop_database('map_reduce_example')

This example shows how to use the
:meth:`~pymongo.collection.Collection.map_reduce` method to perform
map/reduce style aggregations on your data.

.. note::

    Map/Reduce requires server version **>= 1.1.1**. The PyMongo
    :meth:`~pymongo.collection.Collection.map_reduce` helper requires
    PyMongo version **>= 1.2**.

Setup
-----
To start, we'll insert some example data which we can perform
map/reduce queries on:

.. doctest::

  >>> from pymongo import Connection
  >>> db = Connection().map_reduce_example
  >>> db.things.insert({"x": 1, "tags": ["dog", "cat"]})
  ObjectId('...')
  >>> db.things.insert({"x": 2, "tags": ["cat"]})
  ObjectId('...')
  >>> db.things.insert({"x": 3, "tags": ["mouse", "cat", "dog"]})
  ObjectId('...')
  >>> db.things.insert({"x": 4, "tags": []})
  ObjectId('...')

Basic Map/Reduce
----------------
Now we'll define our **map** and **reduce** functions. In this case
we're performing the same operation as in the `MongoDB Map/Reduce
documentation <http://www.mongodb.org/display/DOCS/MapReduce>`_ -
counting the number of occurrences for each tag in the ``tags`` array,
across the entire collection.

Our **map** function just emits a single `(key, 1)` pair for each tag in
the array:

.. doctest::

  >>> from bson.code import Code
  >>> mapper = Code("""
  ...               function () {
  ...                 this.tags.forEach(function(z) {
  ...                   emit(z, 1);
  ...                 });
  ...               }
  ...               """)

The **reduce** function sums over all of the emitted values for a given key:

.. doctest::

  >>> reducer = Code("""
  ...                function (key, values) {
  ...                  var total = 0;
  ...                  for (var i = 0; i < values.length; i++) {
  ...                    total += values[i];
  ...                  }
  ...                  return total;
  ...                }
  ...                """)

.. note:: We can't just return ``values.length`` as the **reduce** function
   might be called iteratively on the results of other reduce steps.

Finally, we call :meth:`~pymongo.collection.Collection.map_reduce` and
iterate over the result collection:

.. doctest::

  >>> result = db.things.map_reduce(mapper, reducer, "myresults")
  >>> for doc in result.find():
  ...   print doc
  ...
  {u'_id': u'cat', u'value': 3.0}
  {u'_id': u'dog', u'value': 2.0}
{'fraction_non_alphanumeric': 0.18587726199842644, 'fraction_numerical': 0.006687647521636507, 'mean_word_length': 2.4948453608247423, 'pattern_counts': {'":': 16, '<': 7, '<?xml version=': 0, '>': 75, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7120379', 'n_tokens_mistral': 1649, 'n_tokens_neox': 1548, 'n_words': 476}