2014-06-09 7 views
5

Sto tentando un'attività abbastanza semplice in arangodb, utilizzando la funzione di aggregazione SUM().Aggregazione in arangodb utilizzando AQL

Ecco una domanda di lavoro che restituisce i dati corretti (anche se non ancora aggregati):

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

Questo restituisce i seguenti risultati:

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

sto usando Raccogliere per raggruppare i risultati perché un dato membroId può avere più oggetti'RegMem '. Come puoi vedere dalla query/risultati, ogni oggetto ha un elenco di oggetti più piccoli chiamati 'elementi', con ogni oggetto con un importo e una descrizione.

Voglio SUM() gli importi per membro. Tuttavia, la regolazione della domanda come questo non funziona:

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

Esso restituisce 0 perché a quanto pare non riesce a trovare un campo nell'elenco voci ampliato chiamato importo.

Guardando i risultati riesco a capire perché: i risultati vengono restituiti in modo tale che gli articoli sono in realtà una lista, di elenchi di oggetti con quantità/descrizione. Ma non capisco come fare riferimento o espandere correttamente l'elenco non nominato per restituire i valori del campo quantità per la funzione SUM().

Idealmente la query deve restituire l'ID membro e l'importo totale, una riga per membro tale che sia possibile rimuovere il filtro ed eseguirlo per tutti i membri.

Mille grazie in anticipo se puoi aiutare! Martin

PS Ho lavorato con il tutorial AQL sul sito Web arangodb e ho controllato il manuale, ma quello che mi avrebbe davvero aiutato sono molte altre query di esempio da esaminare. Se qualcuno sa di una risorsa del genere o vuole condividerne qualcuno, è molto obbligato. Saluti!

risposta

3

Modificato: non letto la domanda per la prima volta. Il primo può essere visto nella storia edit, in quanto contiene anche alcuni suggerimenti:

Ho replicato i dati con la creazione di alcuni documenti in questo formato (e un po 'con una sola voce):

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

Based su alcuni di questi tipi di documenti, la query non riassunto dovrebbe infatti essere simile a questo:

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

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

I dati restituiti:

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

In base alla versione non riepilogata, è necessario scorrere tra gli elementi dei gruppi che sono stati generati dalla funzione di raccolta e fare il vostro SUM() lì. Per poter SUM gli articoli è necessario effettuare il FLATTEN() in un'unica lista, prima di riepilogarli.

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

Questo si traduce in:

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

Grazie mille per il vostro aiuto!Non conoscevo la funzione flatten, ma ricevo un errore quando la invoco: "[1540] uso della funzione sconosciuta 'FLATTEN()'". È definito dall'utente? In ogni caso, accetto la tua risposta con gratitudine perché ho potuto modificare la query che hai fornito nel modo seguente per ottenere il risultato desiderato: PER m IN pkg_spp_RegMem FILTER m.memberId == "40289" membro COLLECT = m.memberId INTO g RETURN {"memberId": membro, "importo": SOMMA ((FOR r IN g [*]. m [*]. articoli FOR i IN r RITORNO i.amount))} – Martin

+1

[FLATTEN()] (https://docs.arangodb.com/Aql/ArrayFunctions.html) è sicuramente una funzione di array standard. A partire dalla v2.7, sarai anche in grado di appiattire con il nuovo operatore multi-star: https://www.arangodb.com/2015/06/aql-improvements-for-2-7/ – CoDEmanX