gpt4 book ai didi

nosql - 如何在图形数据库(如 Neo4j)中建模现实世界的关系?

转载 作者:行者123 更新时间:2023-12-03 12:51:42 25 4
gpt4 key购买 nike

我有一个关于在图形数据库中建模的一般性问题,我似乎无法理解。

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

simple graph ,你可以这样建模:

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

...因此,当您添加更多人和发明时,您将拥有一堆“发明”的图形关系。

问题是,您开始需要向关系中添加一堆属性:
  • 发明日期
  • 有影响力的概念
  • 有影响力的人
  • books_inventor_write

  • ...并且您将要开始在这些属性和其他节点之间创建关系,例如:
  • 影响人:与人节点的关系
  • 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 ”节点链接到“电影”节点的“性能”节点,如下所示: http://www.freebase.com/edit/topic/en/the_last_samurai .不太确定这是否是同一个问题。

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

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

    最佳答案

    其中一些,例如 invention_date , 可以存储为边上的属性,因为在大多数图形数据库中,边可以具有属性,就像顶点可以具有属性一样。例如,您可以执行以下操作(代码如下 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, calculus, "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, newton, principia, "AUTHOR");
    Edge principia_calculus = graph.addEdge(null, principia, calculus, "SUBJECT");

    为了找出牛顿写的所有关于他发现的东西的书,我们可以构建一个图遍历。我们从牛顿开始,按照他的链接找到他发现的东西,然后反向遍历链接以获取有关该主题的书籍,然后再次反向链接以获取作者。如果作者是牛顿,则返回书本并返回结果。这个查询写在 Gremlin ,一种用于图遍历的基于 Groovy 的领域特定语言:
    newton.out("DISCOVERED").in("SUBJECT").as("book").in("AUTHOR").filter{it == newton}.back("book").title.unique()

    因此,我希望我已经展示了如何使用巧妙的遍历来避免创建中间节点来表示边的问题。在小型数据库中这无关紧要,但在大型数据库中,您将遭受巨大的性能损失。

    是的,很遗憾您不能将边与图中的其他边关联起来,但这是这些数据库的数据结构的限制。有时将所有东西都变成一个节点是有意义的,例如,在 Mediator/CVT 中,性能也具有更多的具体性。个人可能希望在评论中只讨论汤姆克鲁斯在“最后的武士”中的表现。但是,对于大多数图形数据库,我发现应用一些图形遍历可以让我从数据库中得到我想要的东西。

    关于nosql - 如何在图形数据库(如 Neo4j)中建模现实世界的关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7536142/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com