Создания семейного древа с СУБД 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. Кроме того, в верхнем левом углу, как Махала Кэмпбелл вышла замуж за своего сводного брата Джона Грира Армстронга. Рядом с Махалой находится Элизабет Кэмпбелл, которая связана браком с другими Кэмпбеллами, но, вероятно, напрямую связана с ними. Точно так же вы можете предположить о Рейчел Джейкобс в правом верхнем углу и как она может относиться к другим Джейкобам. Notice the query.  From the few initial nodes visualized, you can click to open others. Я использую массовые вставки, которые могут заполнить ~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"]