Создания семейного древа с СУБД Neo4j
у меня есть набор данных для семейного дерева в Neo4J и я пытаюсь построить запрос шифрования, который создает набор данных JSON, подобный следующему:
{Name: "Bob",
parents: [
{Name: "Roger",
parents: [
Name: "Robert",
Name: "Jessica"
]},
{Name: "Susan",
parents: [
Name: "George",
Name: "Susan"
]}
]}
мой граф имеет отношение родителя между узлами-членами (т. е. совпадение (p.Member) - [: PARENT] - >(c.Член)). Я нашел вложенные отношения has_many в cypher и neo4j шифр вложенные собирать который в конечном итоге группирует всех родителей вместе для основного дочернего узла, который я ищу для.
добавление некоторой ясности на основе обратной связи:
каждый член имеет уникальный идентификатор. В настоящее время все профсоюзы связаны с родительскими отношениями. Все индексируется, так что производительность не пострадает. Когда я запускаю запрос, чтобы просто вернуть график узла, я получаю результаты, которые я ожидаю. Я пытаюсь вернуть вывод, который я могу использовать для целей визуализации с Д3. В идеале это будет сделано с помощью запроса Cypher, поскольку я использую API для доступа к neo4j из интерфейс строится.
добавление примера запроса:
MATCH (p:Person)-[:PARENT*1..5]->(c:Person)
WHERE c.FirstName = 'Bob'
RETURN p.FirstName, c.FirstName
этот запрос возвращает список каждого родителя для пяти поколений, но вместо того, чтобы показывать иерархию, он перечисляет " Bob " как дочерний для каждого отношения. Есть ли запрос Cypher, который бы показывал каждую связь в данных по крайней мере? Я могу отформатировать его, как мне нужно оттуда...
4 ответов
вы также можете взглянуть на Рик ван Бруггенс блог на его семейных данных:
относительно вашего запроса
вы уже создаете шаблон пути здесь:(p:Person)-[:PARENT*1..5]->(c:Person)
вы можете назначить его переменной tree
и потом работать с этой переменной, например, возвращая дерево, или nodes(tree)
или rels(tree)
или работать с этой коллекцией другими способами:
MATCH tree = (p:Person)-[:PARENT*1..5]->(c:Person)
WHERE c.FirstName = 'Bob'
RETURN nodes(tree), rels(tree), tree, length(tree),
[n in nodes(tree) | n.FirstName] as names
см. также справочную карточку cypher:http://neo4j.com/docs/stable/cypher-refcard и онлайн-тренинг http://neo4j.com/online-training чтобы узнать больше о Cypher.
не забудьте
create index on :Person(FirstName);
Я бы предложил создать метод, чтобы сгладить ваши данные в массив. Если у их объектов нет UUID, вы, вероятно, захотите дать им идентификаторы при сглаживании, а затем иметь ключ parent_id для каждой записи.
затем вы можете запустить его как набор запросов cypher (либо делая несколько запросов к API REST запроса, либо используя API REST пакета)или альтернативно сбросить данные в CSV и использоватьLOAD CSV
команда для загрузки объектов.
пример шифра команда с params будет:
CREATE (:Member {uuid: {uuid}, name: {name}}
а затем снова запуск списка с идентификаторами родителя и ребенка:
MATCH (m1:Member {uuid: {uuid1}}), (m2:Member {uuid: {uuid2}})
CREATE m1<-[:PARENT]-m2
убедитесь, что у вас есть индекс на ID для членов!
генеалогические данные могут соответствовать стандарту GEDCOM и включать два типа узлов: Person и Union. Узел Person имеет свой идентификатор и обычные демографические факты. Узлы объединения имеют union_id и факты о союзе. В GEDCOM семья является третьим элементом, объединяющим эти два элемента. Но в Neo4j я нашел подходящим также включить union_id в узлы Person. Я использовал 5 отношений: отец, мать, муж, жена и ребенок. Семья тогда двое родителей с внутренний вектор и каждый ребенок с внешним вектором. Изображение иллюстрирует это. Это очень удобно для визуализации связей и генерации гипотез. Например, рассмотрим прилагаемую картину и моего предка Эдварда г. Кэмпбелла, продукт Союза 1917 года, где три брата женились на Трех сестрах Воут из Союза 8944 и двух замужних сестрах Гейтер из Союза 2945. Кроме того, в верхнем левом углу, как Махала Кэмпбелл вышла замуж за своего сводного брата Джона Грира Армстронга. Рядом с Махалой находится Элизабет Кэмпбелл, которая связана браком с другими Кэмпбеллами, но, вероятно, напрямую связана с ними. Точно так же вы можете предположить о Рейчел Джейкобс в правом верхнем углу и как она может относиться к другим Джейкобам. Я использую массовые вставки, которые могут заполнить ~30000 узлов человека и ~100 000 отношений чуть более чем за минуту. У меня есть небольшая функция .NET, которая возвращает JSon из dataview; это общее решение работает с любым dataview, поэтому оно масштабируется. Сейчас я работаю над добавление других данных, таких как местоположения (lat/long), документация (особенно связывающая людей, таких как перепись) и т. д.
единственный способ, который я нашел до сих пор, чтобы получить данные, которые я ищу, - это фактически вернуть информацию о взаимоотношениях, например:
MATCH ft = (person {firstName: 'Bob'})<-[:PARENT]-(p:Person)
RETURN EXTRACT(n in nodes(ft) | {firstName: n.firstName}) as parentage
ORDER BY length(ft);
который вернет набор данных, который я смогу преобразовать:
["Bob", "Roger"]
["Bob", "Susan"]
["Bob", "Roger", "Robert"]
["Bob", "Susan", "George"]
["Bob", "Roger", "Jessica"]
["Bob", "Susan", "Susan"]