2017-11-23 1 views
1

Ich möchte diese Abfrage Lehre ODMs Aggregation Builder verwenden zu bauen:Wie summiere ich mehrere Felder in der Lehre Odm?

db.TeamStandings.aggregate(

    // Pipeline 
    [ 
     // Stage 1 
     { 
      $match: { 
       "team.$id": ObjectId("5a1643fdf5d8741a883c2aeb") 
      } 
     }, 

     // Stage 2 
     { 
      $group: { 
       "_id": { "team": "team.$id" }, 

       // This is the sum of multiple fields 
       "games": { $sum: { $sum: ["$wins", "$losses", "$ties"] } }, 

       "wins": { $sum: "$wins" }, 
       "losses": { $sum: "$losses" }, 
       "ties": { $sum: "$ties" }, 
       "homeWins" : { $sum: "$homeRecord.wins" }, 
       "homeLosses" : { $sum: "$homeRecord.losses" }, 
       "homeTies" : { $sum: "$homeRecord.ties" }, 
       "roadWins" : { $sum: "$roadRecord.wins" }, 
       "roadLosses" : { $sum: "$roadRecord.losses" }, 
       "roadTies" : { $sum: "$roadRecord.ties" }, 
      } 
     }, 

    ] 
); 

ich dies in Studio3T ausgeführt und bekam die folgende:

{ 
    "_id" : { 
     "team" : "team.$id" 
    }, 
    "games" : NumberInt(776), 
    "wins" : NumberInt(377), 
    "losses" : NumberInt(398), 
    "ties" : NumberInt(1), 
    "homeWins" : NumberInt(218), 
    "homeLosses" : NumberInt(170), 
    "homeTies" : NumberInt(1), 
    "roadWins" : NumberInt(159), 
    "roadLosses" : NumberInt(228), 
    "roadTies" : NumberInt(0) 
} 

Wie schreibe ich diese genaue Abfrage Lehre ODMs Aggregation Erbauer?

+0

Es gibt ziemlich umfangreiche Dokumentation über den Aggregation Builder: http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/aggregation-builder.html – malarzm

+0

Ob Sie es glauben oder nicht, ich bin schon oft auf dieser Seite gewesen. So begann ich mit dem Aggregation Builder. Allerdings habe ich nicht gesehen, wo es sich um das Zusammenfassen mehrerer Felder handelt. Der spezielle Fall, den ich suche, ist, wie man dies in der Lehre schreibt odm: '" Spiele ": {$ Summe: {$ Summe: [" $ gewinnt "," $ Verluste "," $ Krawatten "] }}, ' – markedphp

+0

Nach dem Graben durch die Doktrin odm' sum() 'Code, der Doc-Block sagt: ' Berechnet und gibt die Summe aller numerischen Werte, die sich aus einen bestimmten Ausdruck auf jedes Dokument in einer Gruppe anwenden von Dokumenten, die die gleiche Gruppe nach Schlüssel teilen. Ignoriert Nonne-numerische Werte. Aber es scheint es _doesnot_; oder wahrscheinlicher verstehe ich den Aggregation Builder nicht. – markedphp

Antwort

0

Dieser ist schwierig, weil die Dokumentation nicht ganz klar ist.

Theoretisch erstellen Sie einen verschachtelten Unterausdruck und verwenden Sie die Summe Operator gibt:

$builder = $this->dm->createAggregationBuilder(\Documents\BlogPost::class); 
$builder->group() 
    ->field('id') 
    ->expression(null) 
    ->field('games') 
    ->sum($builder->expr()->sum('$wins', '$losses', '$ties')) 
; 

jedoch aufgrund der Art und Weise der Aggregation Builder erstellt wird, ist es nicht ganz verstehen, die Summe syntax mit mehrere Ausdrücke außerhalb einer $project Stufe, was zu dem folgende (falsch) Ergebnis:

[{ 
    "$group": { 
     "_id": null, 
     "games": { "$sum": { "$sum": "$wins" } } 
    } 
}] 

, um dieses Problem zu umgehen, verwenden Sie den $add Operator statt $sum in der verschachtelten e xpression:

$builder = $this->dm->createAggregationBuilder(\Documents\BlogPost::class); 
$builder->group() 
    ->field('id') 
    ->expression(null) 
    ->field('games') 
    ->sum($builder->expr()->add('$wins', '$losses', '$ties')) 
; 

Dies erstellt die Aggregationspipeline, die Sie erstellen möchten.

Der Grund dafür ist seltsam ist, weil die Dokumentation unterschiedliche Verhalten für $sum definiert, wann in $group und $project Stufen verwendet: in $group es ein einziges Argument akzeptiert, während in $project es mehrere Argumente akzeptiert. Es ist jedoch nicht völlig klar, wie es sich in einem verschachtelten Ausdruck innerhalb $group verhält: Die Tatsache, dass die von Ihnen gepostete Aggregationspipeline funktioniert, legt nahe, dass der Unterausdruck nicht innerhalb einer $group-Stufe liegt, was mehrere Argumente zulässt. Als ich den Operator baute, nahm ich das Gegenteil an: nur wenn in einer $project Bühne sollte $sum akzeptieren mehrere Argumente und Standard auf die eine Argumentsyntax sonst.

Ich werde ein Ticket dafür in MongoDB ODM erstellen und ich werde sehen, ob dies leicht behoben werden kann.

+0

mit '-> add (...)' gearbeitet ! Vielen Dank. Und danke für die Erstellung eines Tickets.Könnten Sie den Link für das von Ihnen erstellte Ticket posten, damit ich Ihnen folgen kann? Vielen Dank. – markedphp

+0

Sicher, los gehts: https://github.com/doctrine/mongodb-odm/issues/1678 – alcaeus

Verwandte Themen