在Bulbs(neo4j或titan中),更新边缘的正确方法是什么?

3

我正在尝试使用Bulbs与图形数据库进行交互。(实际生产中将使用Titan,在本地实验中似乎Neo4j最好)。

我无法理解这个概念...

Bulbs展示了如何创建新的顶点...

>>> james = g.vertices.create(name="James")
>>> julie = g.vertices.create(name="Julie")
>>> g.edges.create(james, "knows", julie)

深入查看文档,我可以将其替换为“获取或创建”:
>>> james = g.vertices.get_or_create('name',"James",{'name':'james')

我无法想象如何获取现有的Edge。迄今为止,我的尝试都以重新创建了数十个“James认识Julie”的关系结束,而不是访问现有的关系进行更新。
有人可以指点我正确的方向吗?
1个回答

4
您可以添加/更新边的属性,但在图数据库中,您无法更新使其成为边的属性,即无法更新其传入和传出顶点 ID 或标签。相反,您需要删除该边并添加一个新的边。
以下是获取边并更新其属性的不同方式。
您可以通过其 ID 获取边:
>>> from bulbs.rexster import Graph
>>> g = Graph()
>>> james = g.vertices.create(name="James")
>>> julie = g.vertices.create(name="Julie")
>>> edge = g.edges.create(james, "knows", julie)
>>> edge2 = g.edges.get(edge.eid)       # get the edge again
>>> assert edge == edge2
>>> edge2.someprop = "somevalue"
>>> edge2.save()

您可以通过其属性查找边缘,如果它有任何属性并且已经被索引:
# will return an iterator or None edges (may return more than one)
>>> edges = g.edges.index.lookup(someprop="somevalue") 
>>> edge = edges.next()
>>> edge.someprop = "newvalue"
>>> edge.save()

# will return 1 or None edges (or an error if more than 1 edge found)
>>> edge = g.edges.index.get_unique(someprop="somevalue") 
>>> edge.someprop = "newvalue"
>>> edge.save()

您还可以通过遍历Gremlin的顶点来获得优势:
>>> from bulbs.rexster import Graph
>>> g = Graph()
>>> script = "g.V('name',name1).outE(label).as('e').inV.has('name',name2).back('e')"
>>> params = dict(name1="James", label="knows", name2="Julie")
>>> edges = g.gremlin.query(script, params)
>>> edge = edges.next()
>>> edge.someprop = "newvalue"
>>> edge.save()

看到 Gremlin 回溯模式...

但是,更新边缘的最有效方法(当您不知道其ID时)是通过查找该边缘的 Gremlin 脚本进行更新(这样您只需要一次往返就可以访问服务器,而不是两次):

>>> from bulbs.rexster import Graph
>>> g = Graph()
>>> script = "g.V('name',name1).outE(label).as('e').inV.has('name',name2).back('e').sideEffect{it.someprop = someprop}"
>>> params = dict(name1="James", label="knows", name2="Julie", someprop="somevalue")
>>> edges = g.gremlin.query(script, params)
>>> edge = edges.next()
>>> edge.someprop
'somevalue'

查看https://github.com/tinkerpop/gremlin/wiki/Updating-a-Graph。而不是在Python REPL中编写Gremlin一行代码,为了可读性,我会将Gremlin脚本放在一个gremlin.groovy文件中,如下所示:http://bulbflow.com/docs/api/bulbs/groovy/。以下是使用Gremlin获取或创建边的实际示例:https://github.com/espeed/lightbulb/blob/master/lightbulb/gremlin.groovy#L88。并且这里有关于代码的详细说明:Is there a equivalent to commit in bulbs framework for neo4j

看起来neo4j在新版本中引入了g.edges.get_or_create。不确定其他服务器是否也在跟进。我需要尝试一下你的方法。我们正在将一些RDBMS系统转换为图形,有很多批处理工作,我们可能已经创建了一个边缘并希望更新它-而不是重新创建它并使用较少的数据。 - Jonathan Vanasco
1
对于批量更新,通常使用Redis或Java/Groovy内存映射的属性到顶点/边ID。根据您如何预处理数据,可能有意义从Python使用Redis,但通过jedis客户端从Java使用Redis可能更有效率。请参阅我几年前发布的Gremlin用户组帖子:“在实时中让Gremlin与Redis通信,同时遍历图形”(https://groups.google.com/d/topic/gremlin-users/xhqP-0wIg5s/discussion)--您可能需要更新代码以适应最新的Gremlin版本。 - espeed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接