2016-08-11 2 views
1

ich eine Abfrage auf diesem Schema durchführen möchten:Wie eine komplexe Abfrage in MongoDB auszuführen

{ 
    "name" : "xxx", 
    "guests" : [ 
     { 
      "category" : "category 1", 
      "arrived" : false 
     }, 
     { 
      "category" : "category 2", 
      "arrived" : false 
     }, 
     { 
      "category" : "category 1", 
      "arrived" : true 
     }, 
     { 
      "category" : "category 2", 
      "arrived" : true 
     } 
    ] 
} 

ich für einen bestimmten Namen erhalten möchten, eine Liste mit dem Prozentsatz der Gäste für jede Kategorie angekommen.

Für das Dokument oben als Beispiel mag ich erhalten:

{ 
    name : "xxx", 
    results : [ 
     { 
       category : "category 1", 
       arrived : 50 (percent) 
     }, 
     { 
       category : "category 2", 
       arrived : 50 (percent) 
     }, 
    ] 

Gibt es eine Möglichkeit, dies mit einer einzigen MongoDB Abfrage zu tun? Sollte ich diese Berechnung auch auf der Clientseite oder der Serverseite durchführen?

+0

Adressierung, wo Sie die Berechnung tun sollten, in der Regel sollten komplexe Berechnungen auf der Client-Seite als MongoDB erfolgen soll ein großer, stumm Datenspeicher sein, die fast tut nicht wird bearbeitet. Es speichert und ruft nur Daten ab. Sie sollten dieses Ziel respektieren und versuchen, zu vermeiden, dass MongoDB Berechnungen durchführt, die auf dem Client ausgeführt werden können, es sei denn, Sie sind bereit, hohe Leistungseinbußen in Kauf zu nehmen. Selbst "triviale" Aufgaben wie das Finden von Durchschnitten oder Summierungsfeldern sollten generell an den Client weitergegeben werden. – chridam

Antwort

4

Sie können Aggregat verwenden. Hier ein Beispiel:

[ 
    { 
     $match: {name:"xxx"} 
    }, 
    { 
     $unwind: "$guests" 
    }, 
    { 
     $group: { 
      _id:"$guests.category", 
      guests_arrived: { 
       $sum: { $cond: [ {$eq:["$guests.arrived",true]}, 1, 0 ] } 
      }, 
      guests_total: { 
       $sum: 1 
      } 
     } 
    }, 
    { 
     $project:{ 
      _id: false, 
      category: "$_id", 
      guests_arrived:true, 
      guests_total:true, 
      "percent": { 
       $multiply: [ 
        100, 
        {$divide: ["$guests_arrived","$guests_total"]} 
       ] 

      } 
     } 
    } 
] 

Erklärung der Aggregation Pipelinestufen verwendet:

$ passen die auf Namen, da Sie wollen Ergebnisse nur für einen bestimmten Namen

$ Abwickeln die Gäste Array, so dass wir Aggregatfunktionen auf seine Mitglieder in der nächsten Stufe durchführen können

$ group von Kategorie um $ Summe Gesamt Gäste und die Anzahl der Gäste, die $ Cond/$ eq angekommen zu bewerten ist verwendet angekommen sind und fügen Sie nur guests_arrived wenn eingetroffen = true

$ Projekt mit dem primären Zweck der Prozentsatz der Berechnung auf den aggregierten Werten basiert, g uests_arrived und guests_total, von der vorherigen Stufe

+0

danke, es hat funktioniert! Können Sie erklären, was Sie getan haben, damit es funktioniert? – user1941348