"Упорядоченные списки" и двунаправленные однонаправленные отношения
Я новичок в Neo4j, сейчас просто играю в данных моделирования браузеров для проекта.
Вот мой пример использования: у пользователя может быть несколько элементов. Каждый предмет описывается сюжетной линией.
(:User)-[:OWNS]->(:Item)<-[:DESCRIBES]-(:Storyline)
Пока никаких проблем. Тем не менее, сюжетная линия должна содержать "карты", в основном главы истории, которые должны быть в порядке. Итак, моя первая мысль была такая.
(:Storyline)<-[:FOLLOWS]<-(a:Card)<-[:FOLLOWS]-(b:Card)
Однако, если мы начнем с Карты B, теперь мы должны следовать по пути назад, чтобы увидеть, к какой сюжетной линии / предмету принадлежит карта. Кажется неэффективным. Было бы лучше сделать это?
(a:Card {order: 0})-[:BELONGS_TO]->(:Storyline)
(b:Card {order: 1})-[:BELONGS_TO]->(:Storyline)
Or, might I even trash the Storyline and just have the following?
(:Card {order:0})-[:DESCRIBES]->(:Item)
Next, a user should be free to create a link to another storyline card belonging to his own or any other user's item.
(storyA:Card)-[:LINKS_TO]->(storyB:Card)
However, the owner of storyB may or may not want to link back to the first guy's story. I know you can ignore the direction of the relationship in a cypher query by doing:
(a)-[r]-(b)
But I read that explicitly creating bi-directional relationships is usually a bad idea. So if storyB wants to link back, how would you best represent this in the data model? Maybe another relationship type, like:LINKS_MUTUALLY or something, or a "mutual" boolean property on the:LINKS_TO relationship?
1 ответ
Что касается вашей первой проблемы, в этом случае обычно лучше иметь отношения, чем свойства.
Я бы бросил в FIRST
а также LAST
отношения, как в этом TimeTree, и моделировать его как:
(a:Card)-[:DESCRIBES]->(i:Item)
(b:Card)-[:DESCRIBES]->(i:Item)
(c:Card)-[:DESCRIBES]->(i:Item)
(a:Card)<-[:FOLLOWS]-(b:Card)
(b:Card)<-[:FOLLOWS]-(c:Card)
(a:Card)<-[:FIRST_CARD]-(i:Item) //optional, for easy navigation
(c:Card)<-[:LAST_CARD]-(i:Item) //optional, for easy navigation
Что касается двунаправленных отношений, единственная плохая идея, если отношения в одном направлении подразумевают другое. В вашем случае это не так, поэтому создание (storyA:Card)-[:LINKS_TO]->(storyB:Card)
а также (storyA:Card)<-[:LINKS_TO]-(storyB:Card)
это совершенно нормально, так как каждая связь существует по разной причине.