nosql – 如何在图表数据库(如Neo4j)中建立真实世界关系?

前端之家收集整理的这篇文章主要介绍了nosql – 如何在图表数据库(如Neo4j)中建立真实世界关系?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个关于在图形数据库中建模的一般问题,我似乎不能包围我的头。

你如何模拟这种类型的关系:“牛顿发明微积分”?

simple graph,你可以这样建模:

Newton (node) -> invented (relationship) -> Calculus (node)

…所以你会有一堆“发明”的图形关系,因为你添加了更多的人和发明。

问题是,你开始需要为关系添加一堆属性

发明日期
有影响力的概念
有影响力的人
> books_inventor_wrote

…并且您将要开始创建这些属性和其他节点之间的关系,例如:

有影响力的人:与人类节点的关系
> books_inventor_wrote:与书节点的关系

所以现在看来​​,“真实世界的关系”(“发明”)实际上应该是一个图形中的一个节点,图形应该是这样的:

Newton (node) -> (relationship) -> Invention of Calculus (node) -> (relationship) -> Calculus (node)

而更复杂的是,其他人也参与了微积分的发明,所以现在的图形变成了:

Newton (node) -> 
  (relationship) -> 
    Newton's Calculus Invention (node) -> 
      (relationship) -> 
        Invention of Calculus (node) -> 
          (relationship) -> 
            Calculus (node)
Leibniz (node) -> 
  (relationship) -> 
    Leibniz's Calculus Invention (node) -> 
      (relationship) -> 
        Invention of Calculus (node) -> 
          (relationship) -> 
            Calculus (node)

所以我问这个问题,因为你似乎不想在实际的图形数据库“关系”对象上设置属性,因为你可能希望在某些时候将它们视为图中的节点。

它是否正确?

我一直在研究Freebase Metaweb Architecture,他们似乎正在把一切当作一个节点。例如,Freebase有一个Mediator/CVT的想法,您可以在其中创建一个将“Actor”节点链接到“Film”节点的“Performance”节点,如下所示:http://www.freebase.com/edit/topic/en/the_last_samurai.不太确定这是否是同一个问题。

使用哪些指导原则来确定“真实世界关系”是否应该是图形节点而不是图形关系?

如果有关于这个话题的好书,我很想知道。谢谢!

其中的一些这样的东西,如发明日期,可以存储为边缘上的属性,因为大多数图形数据库边缘可以具有与顶点具有属性相同的属性。例如,你可以这样做(代码如下 TinkerPop’s Blueprints):
Graph graph = new Neo4jGraph("/tmp/my_graph");
Vertex newton = graph.addVertex(null);
newton.setProperty("given_name","Isaac");
newton.setProperty("surname","Newton");
newton.setProperty("birth_year",1643); // use Gregorian dates...
newton.setProperty("type","PERSON");

Vertex calculus = graph.addVertex(null);
calculus.setProperty("type","KNOWLEDGE");

Edge newton_calculus = graph.addEdge(null,newton,calculus,"DISCOVERED");
newton_calculus.setProperty("year",1666);

现在,让我们扩展一下,并添加到Liebniz:

Vertex liebniz = graph.addVertex(null);
liebniz.setProperty("given_name","Gottfried");
liebniz.setProperty("surnam","Liebniz");
liebniz.setProperty("birth_year","1646");
liebniz.setProperty("type","PERSON");

Edge liebniz_calculus = graph.addEdge(null,liebniz,"DISCOVERED");
liebniz_calculus.setProperty("year",1674);

加入书籍:

Vertex principia = graph.addVertex(null);
principia.setProperty("title","Philosophiæ Naturalis Principia Mathematica");
principia.setProperty("year_first_published",1687);
Edge newton_principia = graph.addEdge(null,principia,"AUTHOR");
Edge principia_calculus = graph.addEdge(null,"SUBJECT");

为了找出牛顿在他发现的事情上写的所有书,我们可以构建一个图遍历。我们从牛顿开始,从他发现的链接到他发现的东西,然后反过来通过链接获取关于该主题的书籍,并再次在链接上反转以获取作者。如果作者是牛顿,那么回到这本书并返回结果。这个查询是写在Gremlin,一个基于Groovy的域特定语言,用于图遍历:

newton.out("DISCOVERED").in("SUBJECT").as("book").in("AUTHOR").filter{it == newton}.back("book").title.unique()

因此,我希望我已经显示了一个如何巧妙的遍历可以避免创建中间节点来表示边缘的问题。在一个小数据库中,这并不重要,但是在大型数据库中,您将遭受大量的性能攻击。

是的,令人伤心的是,您不能将边与边中的其他边相关联,但这是数据结构的限制。有时把所有的节点都做成一个节点是有意义的,例如在Mediator / CVT中,一个性能也比较具体。个人可能希望只在汤姆·克鲁斯(Tom Cruise)的“最后的武士”表演中发表评论。然而,对于大多数图形数据库,我发现一些图遍历的应用可以让我从数据库中得到我想要的东西。

猜你在找的NoSQL相关文章