2016-07-08 12 views
0

Ich habe Daten, die sich auf bestimmte Produkte und deren Kaufdaten in einer Graphdatenbank in Neo4jAbfrage vergleichen zwei Listen in CQL (Cypher)

Produkte 1. A, B, C, D, E, F, G Kaufdaten 6-08 Juli

Der Kaufmuster sind wie folgt

6. Juli - A, B, C, D 7. Juli - A, B, C, D, E 8. Juli - A , B, D, E, F, G

Das Kaufdatum wird als Attribut in Auftragsknoten gespeichert. (Ieopurchase_date)

schrieb ich eine Cypher Abfrage Anzahl der Käufe pro Tag zählen

Match (o :Order)-[:Contains]->(p :Product) 
return o.purchase_date, count(p) 

Output: 
o.purchase_date  count(p) 
6th July     4 
7th July     5 
8th July     6 

Ich möchte dies ändern abzufragen mir die Gesamtzahl neuer Produkte jeden Tag gekauft zu sagen, im Vergleich zu Der vorherige Tag. d.h. 7. Juli 1 8. Juli 2

Irgendwelche Vorschläge?

+0

Scheint, dass die Rückgabe in einer Abfrage ziemlich schwierig sein kann. Es kann einfacher sein, diese Informationen in der Datenbank selbst zu erstellen und zu speichern, aber nur, wenn Sie sie nur für Aufträge mit aufeinander folgenden Kaufdaten und ohne zusätzliche Filterung oder Kriterien benötigen. Würde das für Sie funktionieren, oder muss es innerhalb einer Abfrage vollständig gelöst sein? – InverseFalcon

+0

Die Art, wie diese Frage formuliert wird, lässt mich fragen, ob dies ein Hausaufgaben- oder Testproblem ist, anstatt eines kleinen Beispiels eines Systems, das Sie implementieren müssen. In jedem Fall würde ich für Ihre Testfälle mit vielfältigeren Produktgruppen arbeiten. Mit Ihren aktuellen Daten gibt es nur 1 oder 2 neue Produkte, und Sie entfernen nie Produkte, scheint anfällig für falsch positive Ergebnisse beim Testen von Lösungen. Versuchen Sie eine andere Kombination, wie 6. - A, B (2 neue) 7. - B, C, D (2 neue) 8. - A, B, C, D, E, F, G (4 neue) 9. - A, Z (1 neu) – InverseFalcon

Antwort

0

Verwenden Sie ein filter function Listen vergleichen:

WITH [ 'A', 'B', 'C', 'D']  as List1, 
    [ 'A', 'B', 'C', 'D', 'E'] as List2 
RETURN FILTER (product in List2 WHERE NOT product in List1) as newProduct 

oder list comprehension

WITH [ 'A', 'B', 'C', 'D']  as List1, 
    [ 'A', 'B', 'C', 'D', 'E'] as List2 
RETURN [product in List2 WHERE NOT product in List1] as newProduct 
1

Ich denke, Sie werden diese anders nähern wollen. Abfragen, bei denen Operationen Daten aus der vorherigen Zeile verwenden müssen, sind sehr schwer zusammenzustellen. Es ist schwierig, einfach zu einem Punkt zu kommen, an dem Sie Daten aus zwei verschiedenen Zeilen gleichzeitig referenzieren können, und es ist ein weiteres schwieriges Problem, die gleiche Operation zwischen jedem Satz von zwei Zeilen durchführen zu können.

Wenn Sie stattdessen eine Beziehung zwischen Ihren Aufträgen haben, wie ein [: Next] zwischen ihnen in aufsteigender Reihenfolge, dann wird dieses Kopfweh eines Problems trivial.

Die folgende Abfrage hat keine Bestellung, ich überlasse das Ihnen, da Ihr Beispiel schlägt vor, dass Kaufdaten im String-Format sein könnten, die nicht ordnungsgemäß so wie sie sind.

Dadurch werden Zeilen mit Auftragspaaren zurückgegeben, die sowohl neue Produkte als auch die Anzahl neuer Produkte zwischen den einzelnen Aufträgen anzeigen. Sie können o1 und/oder NewProds einfach aus Ihrer Rücksendung entfernen, wenn Sie sie nicht benötigen. Dadurch erhalten Sie nur die Bestellung und die Anzahl der neuen Produkte in dieser Reihenfolge.

Das offensichtliche Defizit hier ist, dass die erste der Bestellkette (wo es keine vorherige Bestellung gibt) fehlt.

Die folgende Modifikation sollte das in Ordnung bringen, wenn Sie es brauchen:

MATCH (o1:Order)-[:Next*0..1]->(o2:Order)-[:Contains]->(p2:Product) 
WHERE (o1 = o2 AND NOT (:Order)-[:Next]->(o2) AND (o2)-[:Next]->(:Order)) 
OR NOT (o1)-[:Contains]->(p2) 
WITH o1, o2, COLLECT(p2) AS NewProds 
RETURN o1, o2, NewProds, SIZE(NewProds) AS NewProdCnt 

Die: Das nächste Beziehung zwischen o1 und o2 ist nun optional, so dass diese auf Aufträge ohne vorhergehenden Auftrag entsprechen, aber wir müssen Zählen Sie NUR, wenn es keine vorhergehende Bestellung gibt (andernfalls könnte jede Bestellung mit sich selbst als o1 und o2 übereinstimmen, anstatt nur die Bestellungen am Anfang der Kette), und es hilft, eine zusätzliche Bedingung hinzuzufügen, die die Bestellung haben muss habe eine nächste Bestellung.Dies bedeutet, dass wir nichts für Einzelaufträge zurückbekommen, was wünschenswert sein könnte, wenn die folgenden Beziehungen nur temporär sind oder zwischen bestimmten Aufträgen für das Ausführen dieser Art von Abfrage im laufenden Betrieb erzeugt werden (um dann entfernt zu werden); du würdest nicht irgendwelche anderen Aufträge aufheben wollen, die du nicht interessiertest.

Schließlich gibt es die ganze Verwirrung des Erstellens der folgenden Beziehungen zu beginnen mit. This article hat einige sehr interessante Sachen auf mit verknüpften Listen in Neo4j arbeiten, aber der Teil, der uns jetzt richtig relevant sieht ungefähr so ​​aus (Kopieren und aus dem Artikel geklebt):

... 
WITH elem ORDER BY elem.name ASC 
WITH COLLECT(elem) AS elems 
FOREACH (n IN RANGE(0, LENGTH(elems)-2) | 
    FOREACH (prec IN [elems[n]] | 
    FOREACH (next IN [elems[n+1]] | 
     MERGE prec-[:Next]->next))) 

Sie den Anfang ersetzen sollte und die erste WITH-Klausel mit eigenem Abgleich und Bestellung von interessierten Bestellungen. Sie sammeln sie und durchlaufen diese Liste, um die folgenden Beziehungen zu erstellen. Sie können natürlich ein anderes Label verwenden, insbesondere wenn Sie bereits Folgendes haben oder verwenden möchten: Nächste Beziehungen zwischen Aufträgen für andere Anwendungsfälle (da dies Ihre Abfrage durcheinander bringen würde und das Löschen dieser Beziehungen versehentlich beendet werden könnte) von nicht verwandten Beziehungen mit dem gleichen Label).

Als ich die nächsten Beziehungen aufbaute, stieß ich auf eine kuriose Sache, wo: Nächste Beziehungen erstellt wurden, die von und zum selben Knoten zeigen. Wenn das für Sie geschieht, sollten Sie es bereinigen nach: Next Beziehung Schöpfung mit:

MATCH (a:Order)-[r:Next]->(a) 
DELETE r 

Und später, wenn Ihr: Next-Etiketten sind vorübergehend, und Sie müssen, um aufzuräumen, nachdem Sie haben Haben Sie die Daten, die Sie brauchen, einfach alle löschen: Nächste Beziehungen zwischen den Bestellknoten:

MATCH (:Order)-[r:Next]-(:Order) 
DELETE r