2017-01-28 3 views
0

Neo4j를 사용하여 학교 프로젝트를 진행하고 있으며 문제가 발생했습니다. 지원을 한 모든 학생들에게 시험을 보거나 시험을 보거나 등록한 모든 학생을 ID 또는 색인 번호로 받아보고 싶습니다. 나는 학생과 과목을 속성 (학생) - [시험] - (학생) - [등록] - (시험)과 관계가있는 시험으로 연결했습니다. 아이디로 1 명의 학생이 필요합니다.이 학생과 1 명의 질문을 피험자와의 모든 연결이 필요합니다. 내가 사용Neo4j 다중 관계 쿼리

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) 

쿼리이 하나이지만, 나 데이터를 두 배로 제공하고 종종 잘못입니다 : 데이터베이스는 다음과 같습니다. 특정 학생이 각 시험에 대한 모든 시험과 등록을해야하기 때문에 시험에 응시 한 사람과 등록한 사람, 등록하지 않은 사람, 시험에 응시 한 적이없는 사람의 전체 목록을 얻을 수 있습니다. 그래서 요약, 학생이 중 하나를 등록 또는 시험, 또는 둘 모두로 연결되어

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 

, 나는 말했다에 대한 모든 관계를 얻을 필요가 인덱스 번호에 대한 학생. 그런 다음 모든 주체와의 관계를 계산하기 위해 학생이 몇 번이나 시험에 응시했는지에 대한 데이터가 상기 주제에 대한 관계 시험에 저장됩니다. 또한 마크 < 6 인 모든 학생들은 시험에 응시하지 못했습니다. 그래서 나는 많은 정보를 보유하고 있으며 그것을 관계에서 완전히 사용하려고합니다. 주제와 시험의 수를 곱하면 복잡성이 증가합니다.

+0

오신 것을 환영합니다 스택 오버플로 및 감사에 예제 데이터 세트를 제공합니다. 몇 가지 제안 사항 : 1. 질문에 'cypher'태그를 추가하여 다른 사람들이 쉽게 찾을 수 있도록하십시오. 2. 예제의 날짜가 믹스 구문을 사용하고 있습니다. 3. 시험 실패 조건은 무엇입니까? 쿼리는'<5'를 포함하지만, 텍스트는'<6'을 제안합니다. –

+0

1. 사이퍼 태그를 추가하는 방법을 살펴 보겠습니다. 2. 등급 시스템에서 6-10 점은 통과 표시이며, 누군가가 실패하면 6 점 미만으로 설정됩니다. 5는 통과하거나 실패했으면 표시하지 않거나 다른 것이없는 경우입니다. 3. 학생이 실패했거나하지 않았거나, 관계가 미리 설정되어 있습니다. 제가 원했던 것은 예를 들어, 어떤 학생이 말하기 힘든 학생인지, 그가 통과하려고 시도한 과목들, 그리고 그와 관련된 모든 데이터를 가지고 있는지를 보는 것입니다. 또한 예를 들어, 역행 질의에서 학생들이 가장 열심히 찾은 것을 볼 수 있습니다. 따라서 모든 관계를 볼 필요가 있습니다. – xacegod

답변

1

나는 완전히 아직 요구 사항을 이해하지 않지만, 몇 가지 제안은 :

  • 한 번 학생을 선택하는 MATCH 절을 사용하고 나중에 변수를 다시 사용합니다.
  • WHERE에 조건을 추가하는 대신 {indexnumber: 12000}MATCH 절에 포함하여 코드를 단축 할 수 있습니다.
  • collect(distinct c + c1)을 사용하면 모든 c 요소에 대해 c1 컬렉션이 포함됩니다. 이는 아마도 원하는 것이 아닙니다. (InverseFalcon에 의해 제안 업데이트)

그래서, 등록과 함께,이 같은 쿼리를 실행하는 것, 실패와 성공 시험을 수집 :

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

수집하기 전에 이것들 모두를 맞추는 것을 감안할 때, 당신은 1 톤 귀하가 고유 한 값을 수집하지 않는 한 중복의 각 옵션 경기가 끝나면 수집하는 것이 좋습니다. – InverseFalcon

+0

이 프로젝트에서 테스트하고 사용하고자하는 것은 학생들과 대상을 관계로 연결하는 방법보다는 노드를 노드 사이에 연결하는 대신 도달 대상과 직접 연결하는 것입니다.시험 등록 수 (학생이 몇 번이나 시험에 합격했는지)를 수집하여 정보를 얻으려고했는데 시험에 합격하지 못하면 날짜도 시도도하지 않았고 합격 또는 불합격 인 경우 연결 시험에서, 나는 또한 날짜를 볼 수 있으며, 결국 어떤 과목, 노드입니다. 그래서이 모든 정보를 얻기 위해 1 개의 쿼리를 원했습니다. – xacegod