2015-05-12 7 views
5

Angenommen, mein Schema sieht wie dies zu tun:Wie „Gruppe“ in mongoengine

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

Stellen haben wir diese bestehenden Kategorien: "avengers", "justice-leaguers", "villains", und ich möchte so eine "group by" Abfrage für User.objects.all() auszuführen, dass ich bekommen kann so etwas wie dieses:

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

Oder noch besser:

{ 
"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>] 
} 

Ich habe mir die Dokumente von MongoEngine angesehen und muss noch etwas hilfreiches finden. Danke Leute!

Antwort

2

die aggregation framework verwenden, können Sie nur nach Kategorie $group Dokumente benötigen:

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

Mit der $push Aggregationsfunktion finden Sie ein Array mit all den Benutzernamen teilen die gleiche Kategorie bauen.

Gegeben Sie Beispieldaten:

> 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" } 

Dies erzeugt:

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

Jede Chance, diese Mongoengine mit getan werden könnte? Ich werde das sehr wahrscheinlich in meinem Python-Code anstelle der Mongo-Shell machen. Danke noch einmal! – benjaminz

+0

@benjaminz Ich habe keinen Zugriff auf Mongoengine (und habe es nie benutzt), aber es scheint die erforderliche API zu haben: [mongoengine.queryset.QuerySet.aggregate (* pipeline, ** kwargs)] (http: // docs.mongoengine.org/en/latest/apireference.html#mongoengine.queryset.QuerySet.aggregate) –

+0

Überprüfen Sie diese Antwort: [link] (http://stackoverflow.com/a/24420848/1882331) zur Verwendung von ' Gruppe von 'in Mongoengine. – Yahya

9

Da die OP für mongoengine gefragt (und das ist, was ich brauchte) hier ist ein Beispiel für diese Verwendung mongoengine:

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

Dies wird einen Pymongo-Befehl Cursor Iterator zurückgeben.

print list(categories) 

Wir kommen wieder:

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

Funktioniert nicht. Es ist überhaupt keine Python-Syntax. – SolessChong

+0

@SolessChong ist die richtige Syntax in Ordnung. Es ist eine Python-Liste von Wörterbüchern. Der Grund, warum es nicht mehr funktioniert, ist möglicherweise eine Veränderung des Mongolenminenaggregats. Um es zum Laufen zu bringen, einfach die Liste ablehnen: 'User.objects.aggregate ({...})' 'anstelle von' ([{...}]) '. – Wtower

+0

@Wtower Siehe die Bearbeitung am 21. November. Die Antwort hat Syntaxfehler korrigiert. – SolessChong