10

Sto cercando di fare una query di aggregazione usando flask-mongoengine, e da quello che ho letto non sembra possibile.Query Aggregazione Flask-MongoEngine & PyMongo

Ho esaminato più thread del forum, catene di e-mail e alcune domande su Stack Overflow, ma non ho trovato un buon esempio di come implementare l'aggregazione con la mongoengine.

C'è un commento in this question che dice che devi usare "raw pymongo e funzionalità di aggregazione". Tuttavia, non ci sono esempi di come ciò potrebbe funzionare. Ho armeggiato con Python e ho un'applicazione di base usando il framework Flask, ma scavare nelle applicazioni complete & collegando/interrogando a Mongo è abbastanza nuovo per me.

Qualcuno può fornire un esempio (o un collegamento a un esempio) di come utilizzare i miei modelli di flask-mongoengine, ma eseguire query utilizzando il framework di aggregazione con PyMongo? Ciò richiederà due connessioni a MongoDB (una per PyMongo per eseguire la query di aggregazione e una seconda per la query/inserimento/aggiornamento regolare tramite MongoEngine)?

Un esempio di query di aggregazione vorrei realizzare è la seguente (questa domanda mi fa esattamente le informazioni che voglio nella shell Mongo):

db.entry.aggregate([ 
    { '$group' : 
     { '_id' : { 'carrier' : '$carrierA', 'category' : '$category' }, 
      'count' : { '$sum' : 1 } 
     } 
    } 
]) 

Un esempio di uscita da questa query:

{ "_id" : { "carrier" : "Carrier 1", "category" : "XYZ" }, "count" : 2 } 
{ "_id" : { "carrier" : "Carrier 1", "category" : "ABC" }, "count" : 4 } 
{ "_id" : { "carrier" : "Carrier 2", "category" : "XYZ" }, "count" : 31 } 
{ "_id" : { "carrier" : "Carrier 2", "category" : "ABC" }, "count" : 6 } 

risposta

13

la classe tua definiscono con Mongoengine in realtà ha un metodo _get_collection() che ottiene l'oggetto di collezione "raw" come attuato nel driver pymongo.

io sono solo utilizzando il nome Model qui come segnaposto per la classe attuale stabilito per il collegamento in questo esempio:

Model._get_collection().aggregate([ 
    { '$group' : 
     { '_id' : { 'carrier' : '$carrierA', 'category' : '$category' }, 
      'count' : { '$sum' : 1 } 
     } 
    } 
]) 

modo da poter sempre accedere agli oggetti pymongo senza stabilire una connessione separata. Mongoengine è esso stesso costruito su pymongo.

+0

Impressionante! Grazie mille. Questo è stato un po 'un problema per me nel cercare di trovare una soluzione. Ho provato con il metodo "_get_collection()" ed ero in grado di ottenere l'output da Mongo. – SirCobalt

+0

Risposta brillante !! Solo per aggiungere a questo, se si desidera eseguire la clausola group by solo su determinati record, è possibile utilizzare l'operatore $ match come segue: 'Model._get_collection(). Aggregate ([ { '$ match' : qs._query, }, {'$ group': {'_id': {'vettore': '$ carrierA', 'categoria': '$ categoria'}, 'conteggio': {'$ somma ': 1} } } ]) ' dove qs è un'istanza del queryset di MongoEngine. – Yahya

9

aggregate disponibile da Mongoengine 0.9. Collegamento allo API Reference.

Poiché non esiste alcun esempio di sorta intorno, ecco come si esegue una query di aggregazione utilizzando il framework di aggregazione con Mongoengine> 0,9

pipeline = [ 
    { '$group' : 
    { '_id' : { 'carrier' : '$carrierA', 'category' : '$category' }, 
     'count' : { '$sum' : 1 } 
    } 
    }] 

Model.objects().aggregate(*pipeline) 
+0

Fantastico, grazie – Jivan