【问题标题】:Neo4j Key-Value List recommended implementationNeo4j Key-Value List 推荐实现
【发布时间】:2012-06-28 15:26:35
【问题描述】:

我使用 Neo4j 已经有一段时间了,并且使用 Neo4j 启动并运行了一个应用程序,它的所有工作都非常好,Neo4j 在解决这个问题方面真的很酷,但我现在需要扩展应用程序并拥有一直试图实现。 Neo4j 中的数据键值列表,我不确定最好的方法。

我有一个列表,该列表的长度约为 700 万个元素,因此仅将整个列表存储在内存中并自己管理它有点长。我对此进行了测试,它会消耗 3Gb。

我的选择是:

  • (a) Neo4j 只是不适合这项工作的工具,我应该使用实际的键值数据存储。这样做有点不利,因为我必须为这个数据列表引入另一个数据存储。
  • (b) 使用 Neo4j,通过为每个键值创建一个节点,将键和值设置为节点上的属性,但是除了有一个索引将这些节点组合在一起之外没有任何关系,从而暴露了键的键-value 作为索引上的键。
  • (c) 创建单个节点并将所有键值作为属性保存,这感觉不对,因为在获取节点时会将整个内容加载到内存中,然后我必须在属性中搜索我有兴趣,还不如自己管理列表。
  • (d) 键是实际指向两个节点的两部分键,因此创建关系并将值设置为关系上的属性。我开始走这条路,但是在查找特定键/值时,它并不简单快速,所以放弃了。

选项“a”或“b”感觉不错。
任何意见,将不胜感激。

示例场景

我们有节点 A 和节点 B,这两个节点之间存在关系。 节点都具有“foo”的属性,其中 foo 具有一定的价值。 在此示例中,节点 A 具有 foo=X,节点 B 具有 foo=Y

然后我们有这个 K/V 列表。其中一个 K/V 是 Key:X+Y=Value:Z 因此,最初的想法是在节点 A 和节点 B 之间创建另一个关系,并在持有 Z 的关系上存储一个属性。然后在 'foo' 上创建一个索引,并在新关系上创建一个关系 idx。

当给定 Key X+Y 时获取值。 查找逻辑将是获取节点 A(来自 X)和节点 B(来自 y),然后遍历节点 A 关系到节点 B 查找这种新的关系类型。 虽然这会起作用,但我不喜欢我必须查找与节点之间的所有关系以查找特定类型的事实,这是低效的。尤其是当有许多不同类型的关系时。

所以结论是选择“A”或“B”,或者我正在尝试对 Neo 做一些不切实际的事情。

【问题讨论】:

    标签: neo4j key-value


    【解决方案1】:

    不要试图在 Neo4j 属性中存储 700 万个项目——你是对的,这是错误的。

    Redis 和 Neo4j 通常可以很好地配对,但我不太明白您要做什么或您在“d”中的意思——什么是键/值对,以及它们之间的关系图中的节点和关系?示例会有所帮助。

    更新:使用图形数据库执行此操作的最自然方法是将其作为属性存储在两个节点之间的边缘上。然后你可以使用 Gremlin 来获取它的值。

    例如,要返回存在于具有某些属性的两个顶点(节点)之间的边上的属性:

    start = g.idx('vertices')[[key:value]]            // start vertex
    edge = start.outE(label).as('e')                  // edge
    end = edge.inV.filter{it.someprop == somevalue}   // end vertex
    prop = end.back('e').prop                         // edge property
    return prop
    

    您可以按照您的建议将其存储在索引中,但这会增加系统的复杂性,并且如果您需要在遍历过程中引用数据,那么您将不得不存储重复数据或查找它在 Redis 中进行遍历,可以这样做,参见:

    让 Gremlin 在 Redis 运行时与 Redis 实时对话 https://groups.google.com/d/msg/gremlin-users/xhqP-0wIg5s/bxkNEh9jSw4J

    更新 2:

    如果提前知道顶点ab的ID,那就更简单了:

    g.v(a).outE(label).filter{it.inVertex.id == b}.prop
    

    如果提前知道顶点ab,那么它是:

    a.outE(label).filter{it.inVertex == b}.prop
    

    【讨论】:

    • 我们有节点 A 和节点 B,并且节点 A 和 B 之间有关系。这是给定的。
    • 这就是我最初的想法,但后来放弃了,因为,如何快速找到两个节点之间的边缘。如果节点 A 是起点并且与节点 B 有一条边,与节点 C 有一条边,但遍历的开始/结束节点是提前知道的,即从 A 到 B,如何在没有它查看节点 A 到 C 之间的边。这意味着这样做的唯一方法是从 A 开始,获取一种类型的所有关系,查看每个边的结束节点是谁,直到它与 B 匹配。如果 A 有边许多其他节点,这可能很昂贵。还是我错过了什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    • 2019-08-08
    • 2011-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多