How to make "group by" in mongoengine

Suppose my circuit looks like this:

class User(Document): username = StringField() password = StringField() category = StringField() 

Imagine that we have these existing categories: "avengers", "justice-leaguers", "villains" , and I want to execute the "group by" User.objects.all() for User.objects.all() to get something like this:

 [ [<User: IronMan object>, <User: Thor object>, <User: Hulk object>], [<User: Superman object>,<User: Batman object>], [<User: Ultron object>, <User: Joker object>, <User: LexLuthor object>] ] 

Or even better:

 { "avengers": [<User: IronMan object>, <User: Thor object>, <User: Hulk object>], "justice-leaguers": [<User: Superman object>,<User: Batman object>], "villains": [<User: Ultron object>, <User: Joker object>, <User: LexLuthor object>] } 

I looked through the MongoEngine docs and haven't found anything useful yet. Thank you, guys!

+5
source share
2 answers

Using the aggregation structure , you only need $group documents by category:

 db.User.aggregate([ { $group: { _id: "$category", username: { $push: "$username" }} } ]) 

Using the $ push aggregation function, you will create an array containing the entire username sharing the same category.

Given sample data:

 > db.User.find({},{category:1,username:1,_id:0}) { "category" : "avengers", "username" : "IronMan" } { "category" : "avengers", "username" : "Thor" } { "category" : "avengers", "username" : "Hulk" } { "category" : "justice-leagers", "username" : "Superman" } { "category" : "justice-leagers", "username" : "Batman" } { "category" : "villains", "username" : "Ultron" } { "category" : "villains", "username" : "Joker" } { "category" : "villains", "username" : "LexLuthor" } 

This will give:

 { "_id" : "villains", "username" : [ "Ultron", "Joker", "LexLuthor" ] } { "_id" : "justice-leagers", "username" : [ "Superman", "Batman" ] } { "_id" : "avengers", "username" : [ "IronMan", "Thor", "Hulk" ] } 
+2
source

Since the OP requested mongoengine (and this is what I need), here is an example of this using mongoengine:

 categories = User.objects.aggregate([{ '$group': { '_id': '$category', 'username': { '$push': '$username' }} }]) 

This will return the pymongo command cursor iterator.

 print list(categories) 

Will return:

 [{ "_id": "villains", "username": ["Ultron", "Joker", "LexLuthor"]}, { "_id": "justice-leagers", "username": ["Superman", "Batman"]}, { "_id": "avengers", "username": ["IronMan", "Thor", "Hulk"]}] 
+9
source

All Articles