From 7ac74b1c1f60967852bea294c318adc0a45e347e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastien=20G=C3=A9rard?= Date: Sun, 15 Sep 2019 23:27:34 +0200 Subject: [PATCH 1/2] Document Model.objects.aggregate entrypoint with an example --- docs/guide/querying.rst | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/guide/querying.rst b/docs/guide/querying.rst index 151855a6..50218aed 100644 --- a/docs/guide/querying.rst +++ b/docs/guide/querying.rst @@ -349,9 +349,9 @@ Just as with limiting and skipping results, there is a method on a You could technically use ``len(User.objects)`` to get the same result, but it would be significantly slower than :meth:`~mongoengine.queryset.QuerySet.count`. When you execute a server-side count query, you let MongoDB do the heavy -lifting and you receive a single integer over the wire. Meanwhile, len() +lifting and you receive a single integer over the wire. Meanwhile, ``len()`` retrieves all the results, places them in a local cache, and finally counts -them. If we compare the performance of the two operations, len() is much slower +them. If we compare the performance of the two operations, ``len()`` is much slower than :meth:`~mongoengine.queryset.QuerySet.count`. Further aggregation @@ -386,6 +386,18 @@ would be generating "tag-clouds":: top_tags = sorted(tag_freqs.items(), key=itemgetter(1), reverse=True)[:10] +MongoDB aggregation API +----------------------- +If you need to run aggregation pipelines, MongoEngine provides an entry point to `pymongo's aggregation framework `_ + through :meth:`~mongoengine.queryset.base.aggregate`. Checkout pymongo's documentation for the syntax and pipeline. +An example of its use would be :: + + class Person(Document): + name = StringField() + + pipeline = [{"$project": {"name": {"$toUpper": "$name"}}}] + data = Person.objects().aggregate(*pipeline) # Would return e.g: [{"_id": ObjectId('5d7eac82aae098e4ed3784c7'), "name": "JOHN DOE"}] + Query efficiency and performance ================================ From be2c4f2b3cdfe13d9abe92312409761d91f0040c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastien=20G=C3=A9rard?= Date: Mon, 16 Sep 2019 21:15:35 +0200 Subject: [PATCH 2/2] fix formatting and improve doc based on review --- docs/guide/querying.rst | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/guide/querying.rst b/docs/guide/querying.rst index 50218aed..d64c169c 100644 --- a/docs/guide/querying.rst +++ b/docs/guide/querying.rst @@ -388,15 +388,22 @@ would be generating "tag-clouds":: MongoDB aggregation API ----------------------- -If you need to run aggregation pipelines, MongoEngine provides an entry point to `pymongo's aggregation framework `_ - through :meth:`~mongoengine.queryset.base.aggregate`. Checkout pymongo's documentation for the syntax and pipeline. -An example of its use would be :: +If you need to run aggregation pipelines, MongoEngine provides an entry point `Pymongo's aggregation framework `_ +through :meth:`~mongoengine.queryset.QuerySet.aggregate`. Check out Pymongo's documentation for the syntax and pipeline. +An example of its use would be:: class Person(Document): name = StringField() - pipeline = [{"$project": {"name": {"$toUpper": "$name"}}}] - data = Person.objects().aggregate(*pipeline) # Would return e.g: [{"_id": ObjectId('5d7eac82aae098e4ed3784c7'), "name": "JOHN DOE"}] + Person(name='John').save() + Person(name='Bob').save() + + pipeline = [ + {"$sort" : {"name" : -1}}, + {"$project": {"_id": 0, "name": {"$toUpper": "$name"}}} + ] + data = Person.objects().aggregate(*pipeline) + assert data == [{'name': 'BOB'}, {'name': 'JOHN'}] Query efficiency and performance ================================