2014-06-09 16 views
5

Ich versuche eine ziemlich grundlegende Aufgabe in Arangodb, mit der Summenfunktion SUM().Aggregation in Arangodb mit AQL

Hier ist eine Arbeits Abfrage, die die richtigen Daten zurückgibt (wenn auch noch nicht aggregiert):

FOR m IN pkg_spp_RegMem 
FILTER m.memberId == "40289" 
COLLECT member = m.memberId INTO g 
RETURN { "memberId" : member, "amount" : g[*].m[*].items } 

Das folgende Ergebnisse zurück:

[ 
    { 
    "memberId": "40289", 
    "amount": [ 
     [ 
     { 
      "amount": 50, 
      "description": "some description" 
     } 
     ], 
     [ 
     { 
      "amount": 50, 
      "description": "some description" 
     }, 
     { 
      "amount": 500, 
      "description": "some description" 
     }, 
     { 
      "amount": 0, 
      "description": "some description" 
     } 
     ], 
     [ 
     { 
      "amount": 0, 
      "description": "some description" 
     }, 
     ] 
    ] 
    } 
] 

ich die Ergebnisse der Gruppe sammeln verwende, weil Eine gegebene memberId kann mehrere'RegMem'-Objekte haben. Wie Sie aus der Abfrage/den Ergebnissen sehen können, hat jedes Objekt eine Liste von kleineren Objekten, die "Objekte" genannt werden, wobei jedes Objekt einen Betrag und eine Beschreibung hat.

Ich möchte SUM() die Mengen nach Mitglied. Allerdings Einstellung der Abfrage wie das funktioniert nicht:

FOR m IN pkg_spp_RegMem 
FILTER m.memberId == "40289" 
COLLECT member = m.memberId INTO g 
RETURN { "memberId" : member, "amount" : SUM(g[*].m[*].items[*].amount) } 

Es gibt 0 zurück, weil es offenbar nicht auf ein Feld in der erweiterten Elemente Liste genannt Menge finden.

Mit Blick auf die Ergebnisse kann ich verstehen, warum: Die Ergebnisse werden zurückgegeben, so dass Elemente tatsächlich eine Liste von Listen von Objekten mit Menge/Beschreibung ist. Aber ich verstehe nicht, wie die nicht benannte Liste korrekt referenziert oder erweitert wird, um die Betragsfeldwerte für die Funktion SUM() zurückzugeben.

Idealerweise sollte die Abfrage die memberId und den Gesamtbetrag zurückgeben, eine Zeile pro Mitglied, so dass ich den Filter entfernen und für alle Mitglieder ausführen kann.

Vielen Dank im Voraus, wenn Sie helfen können! Martin

PS Ich habe durch das AQL-Tutorial auf der Arangodb-Website gearbeitet und das Handbuch ausgecheckt, aber was mir wirklich helfen würde, lädt mehr Beispielabfragen, um durchzusehen. Wenn jemand von einer solchen Ressource weiß oder einige von ihnen selbst teilen möchte, ist das sehr wichtig. Prost!

Antwort

3

Bearbeitet: Misread die Frage das erste Mal. Die erste in der edit Geschichte zu sehen ist, wie es auch einige Hinweise enthält:

ich Ihre Daten repliziert, indem sie einige Dokumente in diesem Format zu schaffen (und einige mit nur einem Punkt):

{ 
    "memberId": "40289", 
    "items": [ 
    { 
     "amount": 50, 
     "description": "some description" 
    }, 
    { 
     "amount": 500, 
     "description": "some description" 
    } 
    ] 
} 

Based auf einige dieser Arten von Dokumenten, Ihre nicht-Abfrage zusammengefasst in der Tat wie folgt aussehen sollte:

FOR m IN pkg_spp_RegMem 
FILTER m.memberId == "40289" 
COLLECT member = m.memberId INTO g 

RETURN { "memberId" : member, "amount" : g[*].m[*].items } 

Die Daten zurückgegeben:

[ 
    { 
    "memberId": "40289", 
    "amount": [ 
     [ 
     { 
      "amount": 50, 
      "description": "some description" 
     }, 
     { 
      "amount": 0, 
      "description": "some description" 
     } 
     ], 
     [ 
     { 
      "amount": 50, 
      "description": "some description" 
     }, 
     { 
      "amount": 0, 
      "description": "some description" 
     } 
     ], 
     [ 
     { 
      "amount": 50, 
      "description": "some description" 
     } 
     ], 
     [ 
     { 
      "amount": 50, 
      "description": "some description" 
     }, 
     { 
      "amount": 500, 
      "description": "some description" 
     } 
     ], 
     [ 
     { 
      "amount": 0, 
      "description": "some description" 
     } 
     ], 
     [ 
     { 
      "amount": 50, 
      "description": "some description" 
     }, 
     { 
      "amount": 500, 
      "description": "some description" 
     } 
     ] 
    ] 
    } 
] 

Basierend auf der nicht zusammengefassten Version müssen Sie die Elemente der Gruppen, die von der Sammelfunktion generiert wurden, durchlaufen und Ihre SUM() dort eingeben. Um in der Lage zu sein, die Artikel zu SUMMEN, müssen sie FLATTEN() sie in einer einzigen Liste, bevor sie zusammenfassen.

FOR m IN pkg_spp_RegMem 
FILTER m.memberId == "40289" 
COLLECT member = m.memberId INTO g 

RETURN { "memberId" : member, "amount" : SUM(
               FLATTEN(
                 (
                 FOR r in g[*].m[*].items 
                 RETURN r[*].amount 
                 ) 
                ) 
              ) 
     } 

Daraus ergibt sich:

[ 
    { 
    "memberId": "40289", 
    "amount": 1250 
    } 
] 
+0

Vielen Dank für Ihre Hilfe!Ich wusste nichts über die Funktion flatten, aber ich erhalte einen Fehler beim Aufruf: "[1540] Verwendung der unbekannten Funktion 'FLATTEN()'". Ist es benutzerdefiniert? In jedem Fall akzeptiere ich Ihre Antwort mit Dankbarkeit, da ich in der Lage war, die von Ihnen zur Verfügung gestellte Anfrage zu ändern, um das gewünschte Ergebnis zu erhalten: FÜR m IN pkg_spp_RegMem FILTER m.memberId == "40289" COLLECT Mitglied = m.memberId INTO RETURN {"memberId": member, "amount": SUMME ((FOR ING [*]. m [*]. items FÜR i IN r RETURN i.amount))} – Martin

+1

[FLATTEN()] (https://docs.arangodb.com/Aql/ArrayFunctions.html) ist definitiv eine Standard-Array-Funktion. Ab Version 2.7 können Sie auch mit dem neuen Multi-Star-Betreiber flattern: https://www.arangodb.com/2015/06/aql-improvements-for-2-7/ – CoDEmanX