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?
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.
Most helpful comment
The aggregation pipeline is just a list with a dictionary for each aggregation stage, for example:
For creating a pipeline, you can pretty much follow the MongoDB documentation on aggregation.