2016-04-27 6 views
2

Я бегу в эту стену относительно двунаправленных отношений.Как я могу уменьшить двунаправленные отношения в генеалогическом древе в Neo4j?

Скажем, я пытаюсь создать граф, представляющий семейное древо. Проблема в том, что:
* Тимми может быть братом Сьюзи, но
* Сьюзи не может быть братом Тимми.

Таким образом, возникает необходимость смоделировать это в 2-х направлениях:

enter image description here

(Конечно, технически я мог бы сказать SIBLING_TO и оставить только один край ... что я не уверен, что словарный запас когда я пытаюсь подключить бабушку к внуку.)

Когда все сказано и сделано, я уверен, что нет никакого способа обойти тот факт, что направление имеет значение в этом примере.

Я читал об этом blog post, в отношении общих ошибок Neo4j. Автор утверждает, что эта двунаправленность не является наиболее эффективным способом моделирования данных в Neo4j, и ее следует избегать.

И я согласен. Я создал набор из двух семей:
enter image description here и я обнаружил, что многие запросы, которые я пытался запустить, шли очень медленно. Это связано с тем, что «все связано со всеми» природой графика, по крайней мере, внутри каждого соответствующего семейства.

Мой вопрос:
1) Правильно ли я говорю, что двунаправленность не идеальна?

2) Если это так, то мой пример генеалогического древа, представленного каким-либо другим способом ... и что такое «лучшая практика» во многих ситуациях, когда может возникнуть моя проблема?

3) Если невозможно представить семейное древо иным способом, технически ли возможно писать запросы каким-либо образом, которые затрагивают проблему 1)?

Спасибо, что прочитали это и свои мысли.

+0

двунаправленные ссылки одного и того же имени края являются избыточными и не увеличивают стоимость , брат-к-и-сестре, чтобы передать некоторую информацию, хотя это можно было бы вывести из собственности. a (ребенок) - [: PARENT] -> (родительское) отношение дает вам отношения между родителями и детьми и получает от вас все биологические семейные отношения, и вы можете использовать его для каждого поколения родителей/детей. Шаг детей был бы другим делом. –

ответ

1

Хранение избыточной информации (ваши двунаправленные отношения) в БД никогда не является хорошей идеей. Вот лучший способ представить семейное дерево.

Чтобы указать «родство», вам нужен только один тип отношения, скажем SIBLING_OF, и вам нужно иметь только одну такую ​​связь между двумя родственными узлами.

Чтобы указать родословную, вам нужен только один тип отношений, скажем CHILD_OF, и вам нужно иметь только одну такую ​​связь между ребенком для каждого из своих родителей.

У вас также должна быть метка узла для каждого человека, скажем Person. И каждый человек должен иметь уникальное свойство ID (скажем, id) и какое-то свойство, указывающее пол (скажем, булевое isMale).

С этой очень простой модели данных, вот некоторые примеры запросов:

  1. Чтобы найти Person 123 в сестры (обратите внимание, что модель не определяет направление отношения):

    MATCH (p:Person {id: 123})-[:SIBLING_OF]-(sister:Person {isMale: false}) 
    RETURN sister; 
    
  2. Чтобы найти дедушек 123 человека (обратите внимание, что этот шаблон указывает, что соответствующие пути должны иметь глубину 2):

    MATCH (p:Person {id: 123})-[:CHILD_OF*2..2]->(gf:Person {isMale: true}) 
    RETURN gf; 
    
  3. Чтобы найти человека 123 в правнуки:

    MATCH (p:Person {id: 123})<-[:CHILD_OF*3..3]-(ggc:Person) 
    RETURN ggc; 
    
  4. Чтобы найти человека 123 по материнской дядям:

    MATCH (p:Person {id: 123})-[:CHILD_OF]->(:Person {isMale: false})-[:SIBLING_OF]-(maternalUncle:Person {isMale: true}) 
    RETURN maternalUncle; 
    
+0

Этот ответ был именно тем, что мне нужно было услышать - большое вам спасибо. Хотя идея направления направленности по-прежнему отрывочна в моей голове (зачем применять направление, если оно может или не может быть неуместным?), Идея сокращения избыточности, чтобы у вас было минимальное количество отношений, абсолютно золотисто. Примеры запросов являются фантастическими. Еще раз спасибо. –

0

Я не уверен, что вы знаете, что можно запросить двунаправленное (то есть игнорировать направление). Таким образом, вы можете сделать:

MATCH (a)-[:SIBLING_OF]-(b) 

и так как я не согласен с направлением, оно будет соответствовать в обоих направлениях. Так я предлагаю моделировать вещи.

Как правило, вы только хотите сделать несколько отношений, если хотите на самом деле сохранить другое состояние. Например, отношение KNOWS может применяться только одним способом, поскольку человек A может знать человека B, но B может не знать A. Аналогичным образом, у вас может быть отношение LIKES со значением, показывающим, насколько A подобен B, и могут быть разные сильные стороны «симпатия» в двух направлениях

+0

Согласны ли вы с тем, что «внучка» и «бабушка» - это разные состояния и, следовательно, требуют множественных отношений? –

+0

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

+0

Лучше все же, если это имеет смысл для вас, это найти дедушку и бабушку, сопоставляя путь двух отношений child_of. Но у вас это не всегда есть, и вы все еще хотите представить отношения внуков. –

 Смежные вопросы

  • Нет связанных вопросов^_^