Возврат наборов списков в графовых базах данных

Это дополнительный вопрос из раздела Как моделировать отношения между наборами узлов. Я повторю рекламу на случай, если этот вопрос будет удален или существенно изменен:

В настоящее время я изучаю моделирование высших учебных заведений и других подобных объектов (MATH101, BIOL360, BSc и т. д.), и один из вариантов, который мы рассматриваем, — это графические базы данных. Я не знаком с базами данных графов, кроме как в теории.

Одним из вариантов использования этой базы данных является запрос возможных путей прохождения курсов; например, отвечая на вопрос «какие минимальные комбинации курсов действительны для выполнения требований для получения степени бакалавра компьютерных наук с отличием?». Некоторые из требований будут простыми (квалификация требует, чтобы вы выполнили Comp101, Math101 и Comp201), а некоторые будут предоставлять варианты (требуется, чтобы вы выполнили 80 баллов по статьям, классифицируемым как «научные» работы на уровне 100 или выше).

Я нашел списки neo4j, которые мне показались действительно многообещающими, но то, что я действительно хочу, - это иметь возможность возвращать список списков, где каждый список компонентов представляет один потенциальный путь. Однако я не вижу способа создать такой список списков, поэтому я предполагаю, что у меня что-то не так на концептуальном уровне.

Один из способов сделать это — создать цикл, который просматривает квалификационный узел, выбирает одну возможную комбинацию узлов, рекурсивно выполняет требования этого узла, а затем переходит к следующей возможной комбинации. Как разработчик базы данных, идея использования цикла для того, что теоретически решаемо как операция на основе набора, не дает мне спокойно спать по ночам, поэтому я приложу все усилия, чтобы избежать такой мерзости. Как создать запрос для создания такого набора наборов?

Опять же, я пометил Neo4J, потому что я склоняюсь к нему, поскольку (насколько я могу судить) это наиболее широко известная/используемая графическая СУБД (и у меня было довольно элегантное решение моего предыдущего вопроса, которое работает в этом) , но я открыт для решений и в других базах данных (на самом деле, если это возможно в самом новом предложении SQL Server, это, вероятно, было бы идеально, поскольку на нем есть другая инфраструктура).


person Jeff    schedule 08.04.2018    source источник
comment
На самом деле, я подумываю об удалении этого, поскольку теперь я не совсем уверен, что даже концептуально возможно добиться этого без рекурсии или циклов...   -  person Jeff    schedule 08.04.2018
comment
Я не думаю, что использование рекурсии или циклов необходимо, и использование списков, вероятно, также не является правильным подходом. Мне кажется, что вам просто нужна хорошая модель данных, ориентированная на граф (которая хорошо использует отношения и использует преимущества индексации для запуска запросов).   -  person cybersam    schedule 08.04.2018
comment
Требование списка списков здесь больше похоже на вывод. Вы можете использовать collect() для сбора вещей в виде списков в своем запросе, и в зависимости от запроса вы можете снова использовать collect() для коллекций. Я думаю, что более важно получить хорошую модель для этого, включая способы выражения логики ИЛИ для требований разветвления.   -  person InverseFalcon    schedule 08.04.2018
comment
На самом деле для решения этой проблемы вам может понадобиться нечто большее, чем база данных графа. Objectivity/DB — это объектно-ориентированная база данных с полным набором возможностей графовой базы данных. Его преимущество перед графовыми базами данных заключается в его способности обрабатывать данные, которые значительно сложнее, чем узлы и ребра.   -  person djhallx    schedule 29.06.2021


Ответы (1)


Резюмируя мои комментарии: использование рекурсии или циклов должно быть ненужным, и использование списков, вероятно, также не является правильным подходом. Вы должны просто использовать хорошую модель данных, ориентированную на граф (которая хорошо использует отношения и использует индексирование для запуска запросов).

Рискуя переборщить с этой точкой зрения, приведенный ниже запрос использует довольно простую модель данных для построения части графика для школы:

CREATE
  (sci:Area {name: 'Science'}),
  (hum:Area {name: 'Humanities'}),

  (bio:Department {name: 'Biology'})-[:IN_AREA]->(sci),
  (phy:Department {name: 'Physics'})-[:IN_AREA]->(sci),
  (che:Department {name: 'Chemistry'})-[:IN_AREA]->(sci),
  (eng:Department {name: 'English'})-[:IN_AREA]->(hum),
  (his:Department {name: 'History'})-[:IN_AREA]->(hum),
  (soc:Department {name: 'Sociology'})-[:IN_AREA]->(hum),

  (bioMaj:Major {name: 'Biology'})-[:IN_DEPT]->(bio),
  (phyMaj:Major {name: 'Physics'})-[:IN_DEPT]->(phy),

  (bio101:Course {id: 'Bio101', name: 'Introductory Biology', level: 101, credits: 3})   -[:IN_DEPT]->(bio),
  (che101:Course {id: 'Chem101', name: 'Introductory Chemistry', level: 101, credits: 4})-[:IN_DEPT]->(che),
  (phy101:Course {id: 'Phys101', name: 'Newtonian Physics', level: 101, credits: 5})     -[:IN_DEPT]->(phy),
  (phy201:Course {id: 'Phys201', name: 'Mechanics', level: 201, credits: 4})             -[:IN_DEPT]->(phy),
  (phy202:Course {id: 'Phys202', name: 'Elec & Mag', level: 202, credits: 4})            -[:IN_DEPT]->(phy),
  (eng101:Course {id: 'Eng101', name: 'Intro to Poetry', level: 101, credits: 3})        -[:IN_DEPT]->(eng),
  (eng102:Course {id: 'Eng102', name: 'Intro to Drama', level: 102, credits: 3})         -[:IN_DEPT]->(eng),
  (eng103:Course {id: 'Eng103', name: 'Intro to Fiction', level: 103, credits: 3})       -[:IN_DEPT]->(eng),
  (eng202:Course {id: 'Eng201', name: 'Medieval Literature', level: 201, credits: 4})    -[:IN_DEPT]->(eng),
  (his100:Course {id: 'Hist100', name: 'Global History', level: 100, credits: 3})        -[:IN_DEPT]->(his),
  (soc100:Course {id: 'Soc100', name: 'Intro to Sociology', level: 100, credits: 3})     -[:IN_DEPT]->(soc),

  (fred:Student {id: 123456, name: 'Fred Smith'})-[:HAS_MAJOR]->(bioMaj),
  (sue:Student  {id: 987654, name: 'Sue Jones'})-[:HAS_MAJOR]->(phyMaj),

  (fred)-[:ENROLLED_IN {year: 2017, term: 1, grade: 3.73}]->(bio101),
  (fred)-[:ENROLLED_IN {year: 2017, term: 1, grade: 3.62}]->(eng101),
  (fred)-[:ENROLLED_IN {year: 2017, term: 2, grade: 3.55}]->(che101),
  (fred)-[:ENROLLED_IN {year: 2017, term: 2, grade: 2.95}]->(eng102),
  (fred)-[:ENROLLED_IN {year: 2018, term: 1, grade: 3.13}]->(eng202),
  (fred)-[:ENROLLED_IN {year: 2018, term: 1, grade: 3.68}]->(phy101),
  (sue) -[:ENROLLED_IN {year: 2017, term: 1, grade: 3.55}]->(che101),
  (sue) -[:ENROLLED_IN {year: 2017, term: 1, grade: 3.66}]->(eng101),
  (sue) -[:ENROLLED_IN {year: 2017, term: 2, grade: 3.77}]->(phy201),
  (sue) -[:ENROLLED_IN {year: 2017, term: 2, grade: 3.44}]->(soc100),
  (sue) -[:ENROLLED_IN {year: 2018, term: 1, grade: 3.33}]->(eng202),
  (sue) -[:ENROLLED_IN {year: 2018, term: 1, grade: 3.22}]->(phy101);

Предположим, существует требование, согласно которому все специалисты по естественным наукам должны получить оценку 3.0+ по трем гуманитарным курсам, и по крайней мере один из этих гуманитарных курсов должен иметь уровень 200+.

Мы можем найти всех студентов, изучающих естественные науки, которые выполнили это требование (например, Sue Jones) следующим образом:

MATCH (a1:Area)<-[:IN_AREA]-()<-[:IN_DEPT]-()<-[:HAS_MAJOR]-(student)-[e:ENROLLED_IN]->(course)-[:IN_DEPT]->()-[:IN_AREA]->(a2:Area)
WHERE a1.name = 'Science' AND a2.name = 'Humanities' AND e.grade >= 3.0
WITH student, COLLECT(course) AS courses
WHERE SIZE(courses) >= 3 AND ANY(c IN courses WHERE c.level >= 200)
RETURN student;

И наоборот, мы можем найти всех студентов естественных наук, которые еще не выполнили это требование (например, Fred Smith), следующим образом. (Ниже, если OPTIONAL MATCH и его WHERE не находят соответствия, courses будет пустой коллекцией).

MATCH (a1:Area)<-[:IN_AREA]-()<-[:IN_DEPT]-()<-[:HAS_MAJOR]-(student)
WHERE a1.name = 'Science'
OPTIONAL MATCH (student)-[e:ENROLLED_IN]->(course)-[:IN_DEPT]->()-[:IN_AREA]->(a2:Area)
WHERE a2.name = 'Humanities' AND e.grade >= 3.0
WITH student, COLLECT(course) AS courses
WHERE SIZE(courses) < 3 OR NONE(c IN courses WHERE c.level >= 200)
RETURN student;
person cybersam    schedule 08.04.2018
comment
Это феноменально, спасибо, и еще раз мой мозг был слегка потрясен различными способами мышления в графах по сравнению с реляционными. Мне нужно немного времени, чтобы переварить это, поэтому я приму это, как только закончу этот процесс :) - person Jeff; 08.04.2018