2017-01-28 3 views
0

Ich mache ein Schulprojekt mit Neo4j und habe ein Problem festgestellt. Ich möchte alle Studenten, die sich angemeldet haben, um eine Prüfung abzulegen und eine Prüfung ablegen oder sich für sie anmelden, mit ihrer ID oder Indexnummer. Ich habe Studenten und Fächer mit Prüfungen verbunden, die Beziehungen zu Eigenschaften (STUDENT) - [EXAM] - (SUBJECT) und/oder (STUDENT) - [REGISTRATION] - (EXAM) sind. Ich brauche 1 Student nach ID, alle Verbindungen des Studenten zu Themen in 1 Abfrage. Die Datenbank sieht wie folgt aus:Neo4j multiple Beziehung Abfrage

MERGE (std5:STUDENT { name:'Nola', surname:'Joan', indexnumber:12000, semester:'I' }) 
MERGE (std4:STUDENT { name:'Pola', surname:'Moan', indexnumber:12001, semester:'II' }) 

MERGE (sub1:SUBJECT { name:'Databases', semester:'VII' }) 
MERGE (sub2:SUBJECT { name:'Advanced Databases', semester:'VIII' }) 

MERGE (std5) - [ :EXAM { signed:' ' , mark:6 , date:'12.01.2017.' }] -> (sub1)//mark 6 is passing 
MERGE (std4) - [ :EXAM { signed:' ' , mark:5 , date:'12.01.2017.' }] -> (sub1) 

MERGE (std5) - [ :REGISTRATION {date:"2/11/2015", charge:0, term:'June'}] -> (sub1) 

MERGE (std5) - [ :REGISTRATION {date:"2/11/2016", charge:0, term:'June'}] -> (sub1) 

MERGE (std4) - [ :REGISTRATION {date:"2/11/2015", charge:0, term:'June'}] -> (sub2) 

Die Abfrage, die ich verwendet, um dieses eine, sondern gibt mir die Daten doppelt und oft ist es falsch. Ich benötige für einen bestimmten Studenten alle Prüfungen und Anmeldungen für jede dieser Prüfungen, damit ich eine vollständige Liste der Personen bekommen kann, die eine Prüfung abgelegt oder bestanden haben, sich registriert haben oder sich nie angemeldet und eine Prüfung abgelegt haben.

OPTIONAL MATCH (p:STUDENT) - [d:EXAM] - (c:SUBJECT) 

WHERE p.indexnumber = 12000 and d.mark<5 //failing grade 

WITH collect (distinct c) as c1,d 

OPTIONAL MATCH (p:STUDENT) - [b11:EXAM] - (c:SUBJECT) 

WHERE p.indexnumber = 12000 

WITH p , count(c) as rels, collect(b11) as exams,d,collect(distinct c +c1) as c2 

RETURN p, c2, d, rels , exams 

So zusammenzufassen, Schüler verbunden ist, entweder durch Registrierung oder Prüfung oder beides, ich brauche für für Indexnummer Student sagte, alle diese Beziehungen zu erhalten. Dann alle diese Beziehungen zum Thema zu zählen, da die Daten darüber, wie oft der Schüler die Prüfung abgelegt hat, bei der Beziehungsprüfung zu diesem Thema gespeichert werden. Auch alle Schüler, die die Note < 6 haben, haben die Prüfung nicht bestanden. So halte ich viele Informationen und ich beabsichtige, sie vollständig in Beziehungen zu verwenden. Multiplizieren Sie dies mit der Anzahl der Fächer und Prüfungen, die Komplexität stieg.

+0

Willkommen bei Stack-Überlauf und vielen Dank für Bereitstellen eines Beispieldatensatzes Einige Vorschläge: 1. Bitte fügen Sie der Frage das 'cypher'-Tag hinzu, damit andere es leichter finden, 2. Ihre Daten im Beispiel verwenden eine Mix-Syntax 3. Was ist die Bedingung für das Scheitern der Prüfung? Die Abfrage enthält '<5 ', aber der Text schlägt' <6 'vor. –

+0

1. Ich werde prüfen, wie man Cypher-Tags hinzufügt. 2. In unserem Bewertungssystem sind 6-10 Bestehenszeichen, und wenn jemand versagt hat er seine Markierung auf weniger als 6 gesetzt, 5 ist, wenn er versucht hat, zu bestehen und nicht, niedriger ist für Nichterscheinen oder etwas anderes. 3. Student entweder fehlgeschlagen oder nicht, Beziehung wird im Voraus festgelegt. Ich wollte zum Beispiel herausfinden, welche Fächer für diesen Schüler am härtesten sind, welche Fächer er zu bestehen versuchte usw. und mit all diesen Daten arbeiten. Auch kann ich zum Beispiel sehen, in umgekehrter Abfrage, welche der Fächer Studenten am härtesten finden, etc. Daher die Notwendigkeit, alle Beziehungen zu sehen – xacegod

Antwort

1

ich nicht ganz verstehen Ihre Anforderungen noch nicht, aber ein paar Vorschläge:

  • eine MATCH Klausel Verwenden Sie die Schüler einmal für die Auswahl und die Variable später wiederverwenden.
  • Sie können Ihren Code verkürzen, indem Sie {indexnumber: 12000} in die MATCH Klausel einfügen, anstatt eine Bedingung zu WHERE hinzuzufügen.
  • Verwenden collect(distinct c + c1) enthält die c1 Sammlung für jeden c Element, das ist wahrscheinlich nicht das, was Sie wollen.

Also, die ausgefallenen und erfolgreiche Prüfungen zu sammeln, zusammen mit den Registrierungen, würde ich eine Abfrage wie folgt ausgeführt (aktualisiert, wie durch InverseFalcon vorgeschlagen):

MATCH (p:STUDENT {indexnumber: 12000}) 
OPTIONAL MATCH (p) - [e1:EXAM] -> (c1:SUBJECT) 
WHERE e1.mark < 5 
WITH p, collect(e1) AS failedExams 
OPTIONAL MATCH (p) - [e2:EXAM] -> (c2:SUBJECT) 
WHERE e2.mark >= 5 
WITH p, failedExams, collect(e2) AS successfulExams 
OPTIONAL MATCH (p) - [e3:REGISTRATION] -> (c3:SUBJECT) 
RETURN failedExams, successfulExams, collect(e3) AS examRegistrations 
+1

Vorausgesetzt, dass Sie alle diese vor dem Sammeln zusammen, Sie werden eine Tonne sehen von Duplikaten, es sei denn, Sie sammeln ihre eigenen Werte. Besser nach jedem optionalen Match auf dem Weg zu sammeln. – InverseFalcon

+0

Was ich in diesem Projekt testen und verwenden wollte, ist, wie man Studenten und Subjekt mit Beziehungen verbindet, anstatt einen Knoten dazwischen zu setzen, sondern sie direkt mit dem Subjekt verbindet.Ich hatte gehofft, Informationen zu erhalten, indem ich die Anzahl der Anmeldungen zur Prüfung sammelte (wie oft der Student versuchte, die Prüfung zu bestehen), und in diesen Beziehungen sind Daten von Versuchen oder keine Daten, wenn er es versäumte, auf der Prüfung zu erscheinen, auch wenn er bestanden oder nicht bestanden wurde in der Verbindungsprüfung, wo ich auch das Datum sehen kann, und am Ende welches Thema, das Knoten ist. Also wollte ich in 1 Abfrage all diese Informationen bekommen. – xacegod