21
21
>>> from pymongo import MongoClient
22
22
>>> db = MongoClient().aggregation_example
23
>>> db.things.insert({"x": 1, "tags": ["dog", "cat"]})
25
>>> db.things.insert({"x": 2, "tags": ["cat"]})
27
>>> db.things.insert({"x": 2, "tags": ["mouse", "cat", "dog"]})
29
>>> db.things.insert({"x": 3, "tags": []})
23
>>> result = db.things.insert_many([{"x": 1, "tags": ["dog", "cat"]},
24
... {"x": 2, "tags": ["cat"]},
25
... {"x": 2, "tags": ["mouse", "cat", "dog"]},
26
... {"x": 3, "tags": []}])
27
>>> result.inserted_ids
28
[ObjectId('...'), ObjectId('...'), ObjectId('...'), ObjectId('...')]
30
.. _aggregate-examples:
32
32
Aggregation Framework
33
33
---------------------
49
aggregate requires server version **>= 2.1.0**. The PyMongo
50
:meth:`~pymongo.collection.Collection.aggregate` helper requires
51
PyMongo version **>= 2.3**.
49
aggregate requires server version **>= 2.1.0**.
55
53
>>> from bson.son import SON
56
>>> db.things.aggregate([
57
... {"$unwind": "$tags"},
58
... {"$group": {"_id": "$tags", "count": {"$sum": 1}}},
59
... {"$sort": SON([("count", -1), ("_id", -1)])}
62
{u'ok': 1.0, u'result': [{u'count': 3, u'_id': u'cat'}, {u'count': 2, u'_id': u'dog'}, {u'count': 1, u'_id': u'mouse'}]}
55
... {"$unwind": "$tags"},
56
... {"$group": {"_id": "$tags", "count": {"$sum": 1}}},
57
... {"$sort": SON([("count", -1), ("_id", -1)])}
59
>>> list(db.things.aggregate(pipeline))
60
[{u'count': 3, u'_id': u'cat'}, {u'count': 2, u'_id': u'dog'}, {u'count': 1, u'_id': u'mouse'}]
62
To run an explain plan for this aggregation use the
63
:meth:`~pymongo.database.Database.command` method::
65
>>> db.command('aggregate', 'things', pipeline=pipeline, explain=True)
66
{u'ok': 1.0, u'stages': [...]}
65
68
As well as simple aggregations the aggregation framework provides projection
66
69
capabilities to reshape the returned data. Using projections and aggregation,
76
79
Another option for aggregation is to use the map reduce framework. Here we
77
will define **map** and **reduce** functions to also count he number of
80
will define **map** and **reduce** functions to also count the number of
78
81
occurrences for each tag in the ``tags`` array, across the entire collection.
80
83
Our **map** function just emits a single `(key, 1)` pair for each tag in
171
174
.. note:: Doesn't work with sharded MongoDB configurations, use aggregation or
172
175
map/reduce instead of group().
174
Here we are doing a simple group and count of the occurrences ``x`` values:
177
Here we are doing a simple group and count of the occurrences of ``x`` values:
181
>>> from bson.code import Code
178
182
>>> reducer = Code("""
179
183
... function(obj, prev){
180
184
... prev.count++;
184
>>> from bson.son import SON
185
188
>>> results = db.things.group(key={"x":1}, condition={}, initial={"count": 0}, reduce=reducer)
186
189
>>> for doc in results: