2016-05-16 13 views
0

Wir haben Bestellungen, die "verursachte_Ordnung" -Kanten von Bestellung zu Bestellung enthalten, weil Freunde andere Freunde dazu bewegen können, Einkäufe zu tätigen. Wir wissen aus den Links, die wir für die Freunde generieren, dass Order ID 42 Order ID 47 verursacht hat, also erstellen wir eine Kante "created_order" zwischen den beiden Order-Knoten.OrientDB Quersumme und Gruppe nach oberstem Datensatz

Wir suchen nach den Personen, die das am meisten empfohlene Geschäft generieren. Im Moment durchlaufen wir nur C# und finden es heraus, weil unsere Datensätze relativ klein sind. Aber ich würde gerne herausfinden, ob es eine Möglichkeit gibt, stattdessen Traverse SQL zu verwenden.

Das Problem, in das ich renne, ist eine genaue Zählung/Summe für jede Originalauftrags-ID.

sich das folgende Szenario:

Auftrag 42 vier weitere Aufträge verursacht, einschließlich Bestellung 47. Bestellung 47 2 weitere Aufträge verursacht. Und Befehl 51, unabhängig von 42 oder 47, verursachte 3 Befehle.

kann ich die folgende SQL ausführen, um die besten Referrer für diese spezifische bekommen {ProductId}:

select in_caused_order[0].id as OrderID, count(*) as ReferCount, sum(amount) as ReferSum 
from (traverse out('caused_order') from Order) 
where out_includes.id = '{ProductId}' and $depth >= 1 
group by in_caused_order[0].id 

EDIT: das Schema ein wenig komplexer als das ist, ich war darunter nur die out_includes WHERE Klausel, um zu zeigen, dass die Orders etwas gefiltert werden. Aber es ist ein bisschen wie:

Product(V) <-- includes(E) <-- Order(V) --> caused_order(E) --> Order(V) 
(the Order vertex has "amount" as a property, which stores the money spent and is being SUM'd in the SELECT, along with a few fields like date which aren't important) 

Aber das wird wie in etwas führen:

OrderID | ReferCount | ReferSum 
42  | 4   | 525 
47  | 2   | 130 
51  | 3   | 250 

Abgesehen davon, dass nicht ganz richtig ist, oder? Weil Order 42 auch technisch die beiden 47 Bestellungen verursacht hat. So würden wir etwas wie sehen möchten:

OrderID | ReferCount | ReferSum | ExtendedCount | ExtendedSum 
42  | 4   | 525  | 2    | 130 
47  | 2   | 130  | 0    | 0 
51  | 3   | 250  | 0    | 0 

Ich erkenne, dass die beiden "Extended" count/sum Spalten möglicherweise knifflig sein. Wir müssen die Abfrage möglicherweise zweimal ausführen, einmal mit $ depth = 1 und erneut mit $ depth> 1, und dann die Ergebnisse dieser beiden Abfragen in C# zusammenfassen, was in Ordnung ist.

Aber ich kann nicht einmal herausfinden, wie man die Gesamtsumme richtig berechnet. Der erste Schritt wäre auch wie etwas zu sehen sein:

OrderID | ReferCount | ReferSum 
42  | 6   | 635  <-- includes its 4 orders + 47's 2 orders 
47  | 2   | 130 
51  | 3   | 250 

Und da diese n-Ebene tief sein kann, es ist nicht wie kann ich irgendwie tun in_caused_order.in_caused_order.in_caused_order nur in der SQL, ich weiß nicht, Wie viel tief wird das gehen? Auftrag 83 könnte durch Auftrag 47 verursacht werden und Auftrag 105 könnte durch Auftrag 83 verursacht werden, und so weiter.

Jede Hilfe würde sehr geschätzt werden. Oder vielleicht ist die Antwort, Traverse kann damit nicht umgehen, und wir müssen etwas völlig anderes herausfinden.

+0

Ich würde gerne helfen, aber Ihre Domain ist mir nicht klar. Was ist out_includes? Könnten Sie ein Diagramm anfügen, das Beziehungen und Attribute erklärt? – Lvca

+0

@Lvca hi, es ist nur eine Out-Kante zum Produkt-Vertex (was eine Vereinfachung unseres Schemas ist, aber ich wollte zeigen, dass es dort auch eine WHERE-Klausel gibt, um zu filtern welche Bestellungen wir auswählen). Ich habe den Beitrag aktualisiert, danke! –

Antwort

0

ich Ihre usecase bin versucht, finden Sie meine Testdaten:

create class caused_order extends e 
create class Order extends v 
create property Order.id integer 
create property Order.amount integer 

begin 
create vertex Order set id=1 ,amount=1 
create vertex Order set id=2 ,amount=5 
create vertex Order set id=3 ,amount=11 
create vertex Order set id=4 ,amount=23 
create vertex Order set id=5 ,amount=31 
create vertex Order set id=6 ,amount=49 
create vertex Order set id=7 ,amount=4 
create vertex Order set id=8 ,amount=74 
create vertex Order set id=9 ,amount=87 

create edge caused_order from (select from Order where id=1) to (select from Order where id=2) 
create edge caused_order from (select from Order where id=1) to (select from Order where id=3) 
create edge caused_order from (select from Order where id=2) to (select from Order where id=4) 
create edge caused_order from (select from Order where id=2) to (select from Order where id=5) 
create edge caused_order from (select from Order where id=6) to (select from Order where id=7) 
create edge caused_order from (select from Order where id=6) to (select from Order where id=8) 
commit retry 20 

enter image description here


dann schrieb ich diese zwei Abfragen Aufträge mit relativ referSum und ReferCount zu zeigen.

Zuerst einem einschließlich Kopf, um in der Zählung:

select id as OrderID, $a[0].Amount as ReferSum, $a[0].Count as ReferCount from Order 

let $a=(select sum(amount) as Amount, count(*) as Count from (traverse out('caused_order') from $parent.$current) group by Amount) 

enter image description here

zweite, mit Ausnahme des Kopfes:

select id as OrderID, $a[0].Amount as ReferSum, $a[0].Count as ReferCount from Order 

let $a=(select sum(amount) as Amount, count(*) as Count from (select from (traverse out('caused_order') from $parent.$current) where $depth>=1) group by Amount) 

enter image description here


EDIT ich diese zu meinen Daten hinzugefügt haben:

create class includes extends E 
create class Product extends V 
create property Product.id Integer 

create vertex Product set id = 101 
create vertex Product set id = 102 
create vertex Product set id = 103 
create vertex Product set id = 104 

create edge includes from (select from Order where id=1) to (select from Product where id=101) 
create edge includes from (select from Order where id=2) to (select from Product where id=102) 
create edge includes from (select from Order where id=3) to (select from Product where id=103) 
create edge includes from (select from Order where id=4) to (select from Product where id=104) 
create edge includes from (select from Order where id=5) to (select from Product where id=101) 
create edge includes from (select from Order where id=6) to (select from Product where id=102) 
create edge includes from (select from Order where id=7) to (select from Product where id=103) 
create edge includes from (select from Order where id=8) to (select from Product where id=104) 
create edge includes from (select from Order where id=9) to (select from Product where id=101) 
create edge includes from (select from Order where id=1) to (select from Product where id=102) 
create edge includes from (select from Order where id=1) to (select from Product where id=103) 
create edge includes from (select from Order where id=2) to (select from Product where id=104) 

und diese sind die modifizierten Abfragen (hinzugefügt, um die while out('includes').id contains {prodID_number} in Traverse und where out('includes').id contains {prodID_number}:

select id as OrderID, $a[0].Amount as ReferSum, $a[0].Count as ReferCount from Order 

let $a=(select sum(amount) as Amount, count(*) as Count from (traverse out('caused_order') from $parent.$current while out('includes').id contains 102) group by Amount) 

where out('includes').id contains 102 

enter image description here

select id as OrderID, $a[0].Amount as ReferSum, $a[0].Count as ReferCount from Order 

let $a=(select sum(amount) as Amount, count(*) as Count from (traverse out('caused_order') from $parent.$current while out('includes').id contains 102) where $depth >= 1 group by Amount) 

where out('includes').id contains 102 

enter image description here

+0

danke. Die Testdaten sehen korrekt aus und Ihre SQL-Ergebnisse sehen korrekt aus, aber wenn ich sie lokal ausführe, erhalte ich nur eine Liste aller OrderIDs in der Datenbank, also bin ich mir nicht sicher, was nicht in unsere Instanz übersetzt wird :(Auch wenn wir wollten es nur auf Bestellungen eines bestimmten Produkts beschränken (die "out_includes [0] .id = '{ProductId}'" wo würde das in der Abfrage gehen? –

+0

Ich werde meine ans bearbeiten –

+0

danke. wenn ich laufe Ich bekomme OrderIDs immer noch zurück, ohne irgendwelche Summen/Zählungen, und ich denke, ich lerne immer noch, wie LET funktioniert und verbindet sich mit SELECT über $ parent. $ current? aber vielleicht fehlt mir die Summe/Anzahl innerhalb der LET bekommen Sie die richtige OrderID in der Auswahl? –