2014-06-09 11 views
5

Próbuję wykonać dość podstawowe zadanie w arangodb, używając funkcji agregującej SUM().Agregacja w arangodb przy użyciu AQL

Oto zapytanie roboczej, która zwraca odpowiednie dane (choć jeszcze nie zagregowane):

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

ta zwraca następujące wyniki:

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

używam zbierać do grupy rezultaty, ponieważ dany memberId może mieć wiele obiektów'RegMem '. Jak widać z zapytania/wyników, każdy obiekt ma listę mniejszych obiektów zwanych "przedmiotami", z których każdy ma określoną ilość i opis.

Chcę SUMA() kwoty według członków. Jednak dostosowanie kwerendy takiej jak ta nie działa:

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

Zwraca 0, ponieważ najwyraźniej nie może znaleźć pola na liście pozycji rozszerzonych o nazwie kwota.

Patrząc na wyniki, potrafię zrozumieć, dlaczego: wyniki są zwracane w taki sposób, że rzeczy są faktycznie listami, listami obiektów z kwotą/opisem. Ale nie rozumiem, jak poprawnie odwołać lub rozwinąć listę bez nazwy, aby zwrócić wartości pól ilości dla funkcji SUMA().

Idealnie zapytanie powinno zwracać wartość memberId i total, jeden wiersz na element członkowski tak, że mogę usunąć filtr i wykonać dla wszystkich członków.

Bardzo dziękuję z góry, jeśli możesz pomóc! Martin

PS Pracowałem przez samouczek AQL na stronie arangodb i sprawdziłem instrukcję, ale to, co naprawdę mi pomogło, to ładuje więcej przykładowych zapytań do przejrzenia. Jeśli ktokolwiek zna taki zasób lub chce się podzielić swoimi własnymi, "bardzo zobowiązany. Twoje zdrowie!

Odpowiedz

3

Edytowane: błędne przeczytanie pytania po raz pierwszy. Pierwszy z nich można zobaczyć w historii edit, ponieważ zawiera ona również pewne wskazówki:

I replikowane dane, tworząc jakieś dokumenty w tym formacie (a niektóre z tylko jedną pozycję):

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

Based na niektóre z tych typów dokumentów, swoją non-zestawione zapytania powinny być rzeczywiście wygląda tak:

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

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

dane zwracane:

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

Na podstawie nieskonfigurowanej wersji należy przejrzeć pozycje grup, które zostały wygenerowane przez funkcję gromadzenia i wykonać tam swoje SUM(). Aby móc podsumować elementy, musisz je FLATTEN() utworzyć na jednej liście, zanim je podsumujesz.

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

Wynika to z:

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

Dziękuję bardzo za pomoc!Nie wiedziałem o funkcji spłaszczania, ale otrzymuję komunikat o błędzie podczas wywoływania: "[1540] użycie nieznanej funkcji" FLATTEN() "". Czy jest zdefiniowany przez użytkownika? W każdym przypadku akceptuję twoją odpowiedź z wdzięcznością, ponieważ mogłem zmodyfikować zapytanie, które podałeś w następujący sposób, aby uzyskać pożądany wynik: FOR m IN pkg_spp_RegMem FILTR m.memberId == "40289" COLLECT członek = m.memberId INTO g POWRÓT {"memberId": member, "amount": SUM ((DLA r IN g [*]. m [*]. items FOR i IN r RETURN i.amount))} – Martin

+1

[FLATTEN()] (https://docs.arangodb.com/Aql/ArrayFunctions.html) jest zdecydowanie standardową funkcją tablicową. Począwszy od wersji 2.7, będziesz mógł również spłaszczyć z nowym operatorem obsługującym wiele gwiazd: https://www.arangodb.com/2015/06/aql-improvements-for-2-7/ – CoDEmanX