Mongoengine: What is the right way to use "aggregate" in MongoEngine?

Created on 13 Mar 2016  路  3Comments  路  Source: MongoEngine/mongoengine

As "distance" is the default sort order for $near, and my use case requires "distance" to be the secondary sort order, I have to use aggregation pipeline with $geoNear.
I did check out MongoEngine doc for aggregation, but seems it's not clear enough for it.

So my question is: what is the right way to use "aggregate" in MongoEngine?

Question

Most helpful comment

The aggregation pipeline is just a list with a dictionary for each aggregation stage, for example:

pipeline = [
{ "$match": { <query> } },
{ "$geoNear": { <geoNear options> } }
]
results = list(Foo.objects.aggregate(*pipeline))

For creating a pipeline, you can pretty much follow the MongoDB documentation on aggregation.

All 3 comments

The aggregation pipeline is just a list with a dictionary for each aggregation stage, for example:

pipeline = [
{ "$match": { <query> } },
{ "$geoNear": { <geoNear options> } }
]
results = list(Foo.objects.aggregate(*pipeline))

For creating a pipeline, you can pretty much follow the MongoDB documentation on aggregation.

That's it. Thanks @sebastiancodes.

@kevin0571, you can take inspiration in aggregate_sum.

Note that AFAIU

results = list(Foo.objects.aggregate(*pipeline))

is pymongo 3 only. See in aggregate_sum:

    if IS_PYMONGO_3:
        result = list(result)
    else:
        result = result.get('result')
    if result:
        return result[0]['total']
    return 0

Actually, aggregate_sum should not be copied as is, because it uses _collection.aggregate whereas aggregate calls BaseQuerySet.aggregate which in turns calls _collection.aggregate with cursor={}:

return self._collection.aggregate(pipeline, cursor={}, **kwargs)

According to the docs:

Changed in version 2.7: When the cursor option is used, return CommandCursor instead of Cursor.

So even with pymongo 2.7, a CommandCursor is returned, and list(result) is the way to go. Sorry about the noise.

Was this page helpful?
0 / 5 - 0 ratings