如何使用 Gremlin/Titan/TinkerPop3 更新特定边 属性?
How do I update a specific edge property using Gremlin/Titan/TinkerPop3?
目标
我要完成的任务非常简单:设置特定边的权重 属性。以此场景为例:
我想做的是更新 weight
的值。
附加要求
- 如果边不存在,应该创建它。
- 两个节点之间最多只能存在一条相同类型的边(即,Joey 和披萨。
- 任务应该使用 Java API of Titan (which includes Gremlin as part of TinkerPop 3) 解决。
我所知道的
我有以下信息:
我想到的
我认为我需要执行以下操作:
- 从乔伊顶点开始
- 找到所有标记为
votes_for
且具有 type
“吃”的传出边(最多应为 1)和标记为“餐”且具有 name
“比萨”的传出顶点。
- 更新边的
weight
值。
这是我在代码中搞砸的内容:
//vertex is Joey in this case
g.V(vertex.id())
.outE("votes_for")
.has("type", "eat")
//... how do I filter by .outV so that I can check for "pizza"?
.property(Cardinality.single, "weight", 0.99);
//... what do I do when the edge doesn't exist?
如代码中所述,仍然存在问题。明确指定 Titan 模式会有帮助吗?有没有我不知道的 helper/utility 方法?使用多个 vote_for
标签而不是一个标签 + type
属性 是否更有意义,例如 vote_for_eat
?
感谢您的帮助!
你走在正确的轨道上。查看 vertex steps documentation.
标记边,然后从边遍历到顶点检查,然后跳回边更新属性。
g.V(vertex.id()).
outE("votes_for").has("type", "eat").as("e").
inV().has("name", "pizza").
select("e").property("weight", 0.99d).
iterate()
完整的 Gremlin 控制台会话:
gremlin> Titan.version()
==>1.0.0
gremlin> Gremlin.version()
==>3.0.1-incubating
gremlin> graph = TitanFactory.open('inmemory'); g = graph.traversal()
==>graphtraversalsource[standardtitangraph[inmemory:[127.0.0.1]], standard]
gremlin> vertex = graph.addVertex(T.label, 'user', 'given_name', 'Joey', 'family_name', 'Tribbiani')
==>v[4200]
gremlin> pizza = graph.addVertex(T.label, 'meal', 'name', 'pizza')
==>v[4104]
gremlin> votes = vertex.addEdge('votes_for', pizza, 'type', 'eat', 'weight', 0.8d)
==>e[1zh-38o-4r9-360][4200-votes_for->4104]
gremlin> g.E(votes).valueMap(true)
==>[label:votes_for, weight:0.8, id:2rx-38o-4r9-360, type:eat]
gremlin> g.V(vertex.id()).outE('votes_for').has('type','eat').as('e').inV().has('name','pizza').select('e').property('weight', 0.99d).iterate(); g.E(votes).valueMap(true)
==>[label:votes_for, weight:0.99, id:2rx-38o-4r9-360, type:eat]
明确指定 Titan 模式会有帮助吗?
如果您想从 Joey
节点开始而不引用 vertex
或其 id
,这将是 Titan [=23] 的一个很好的用例=].遍历将从以下内容开始:
g.V().has("given_name", "Joey")
有什么我不知道的helper/utility方法吗?
除了TinkerPop reference documentation之外,还有几个教程可以通读:
使用多个 vote_for 标签而不是一个标签 + 输入 属性 是否更有意义,例如 vote_for_eat?
取决于您的图形模型或查询模式,但像 vote_for_eat
这样更细化的标签可以很好地工作。您可以在遍历步骤上传递多个边标签:
g.V(vertex.id()).outE('vote_for_eat', 'vote_for_play', 'vote_for_sleep')
更新
两个节点之间最多只能存在一条相同类型的边
您可以使用 Titan 模式来帮助解决这个问题,具体定义一个 edge label with multiplicity ONE2ONE
。如果在 Joey
和 pizza
.
之间创建多个 votes_for_eat
将抛出异常
Jason 已经回答了你几乎所有的问题。唯一缺少的方面是:
If the edge does not exist, it should be created.
因此,我将尝试使用稍微不同的查询来回答这一点。如果新边不存在,此查询将添加一条新边,然后更新/添加 weight
属性:
g.V(vertex.id()).outE('votes_for').has('type', 'eat')
.where(__.inV().hasLabel('meal').has('name','pizza')) // filter for the edge to update
.tryNext() // select the edge if it exists
.orElseGet({g.V(vertex.id()).next()
.addEdge('votes_for', g.V(pizzaId).next(), 'type', 'eat')}) // otherwise, add the edge
.property('weight', 0.99) // finally, update / add the 'weight' property
目标
我要完成的任务非常简单:设置特定边的权重 属性。以此场景为例:
我想做的是更新 weight
的值。
附加要求
- 如果边不存在,应该创建它。
- 两个节点之间最多只能存在一条相同类型的边(即,Joey 和披萨。
- 任务应该使用 Java API of Titan (which includes Gremlin as part of TinkerPop 3) 解决。
我所知道的
我有以下信息:
我想到的
我认为我需要执行以下操作:
- 从乔伊顶点开始
- 找到所有标记为
votes_for
且具有type
“吃”的传出边(最多应为 1)和标记为“餐”且具有name
“比萨”的传出顶点。 - 更新边的
weight
值。
这是我在代码中搞砸的内容:
//vertex is Joey in this case
g.V(vertex.id())
.outE("votes_for")
.has("type", "eat")
//... how do I filter by .outV so that I can check for "pizza"?
.property(Cardinality.single, "weight", 0.99);
//... what do I do when the edge doesn't exist?
如代码中所述,仍然存在问题。明确指定 Titan 模式会有帮助吗?有没有我不知道的 helper/utility 方法?使用多个 vote_for
标签而不是一个标签 + type
属性 是否更有意义,例如 vote_for_eat
?
感谢您的帮助!
你走在正确的轨道上。查看 vertex steps documentation.
标记边,然后从边遍历到顶点检查,然后跳回边更新属性。
g.V(vertex.id()).
outE("votes_for").has("type", "eat").as("e").
inV().has("name", "pizza").
select("e").property("weight", 0.99d).
iterate()
完整的 Gremlin 控制台会话:
gremlin> Titan.version()
==>1.0.0
gremlin> Gremlin.version()
==>3.0.1-incubating
gremlin> graph = TitanFactory.open('inmemory'); g = graph.traversal()
==>graphtraversalsource[standardtitangraph[inmemory:[127.0.0.1]], standard]
gremlin> vertex = graph.addVertex(T.label, 'user', 'given_name', 'Joey', 'family_name', 'Tribbiani')
==>v[4200]
gremlin> pizza = graph.addVertex(T.label, 'meal', 'name', 'pizza')
==>v[4104]
gremlin> votes = vertex.addEdge('votes_for', pizza, 'type', 'eat', 'weight', 0.8d)
==>e[1zh-38o-4r9-360][4200-votes_for->4104]
gremlin> g.E(votes).valueMap(true)
==>[label:votes_for, weight:0.8, id:2rx-38o-4r9-360, type:eat]
gremlin> g.V(vertex.id()).outE('votes_for').has('type','eat').as('e').inV().has('name','pizza').select('e').property('weight', 0.99d).iterate(); g.E(votes).valueMap(true)
==>[label:votes_for, weight:0.99, id:2rx-38o-4r9-360, type:eat]
明确指定 Titan 模式会有帮助吗?
如果您想从 Joey
节点开始而不引用 vertex
或其 id
,这将是 Titan [=23] 的一个很好的用例=].遍历将从以下内容开始:
g.V().has("given_name", "Joey")
有什么我不知道的helper/utility方法吗?
除了TinkerPop reference documentation之外,还有几个教程可以通读:
使用多个 vote_for 标签而不是一个标签 + 输入 属性 是否更有意义,例如 vote_for_eat?
取决于您的图形模型或查询模式,但像 vote_for_eat
这样更细化的标签可以很好地工作。您可以在遍历步骤上传递多个边标签:
g.V(vertex.id()).outE('vote_for_eat', 'vote_for_play', 'vote_for_sleep')
更新
两个节点之间最多只能存在一条相同类型的边
您可以使用 Titan 模式来帮助解决这个问题,具体定义一个 edge label with multiplicity ONE2ONE
。如果在 Joey
和 pizza
.
votes_for_eat
将抛出异常
Jason 已经回答了你几乎所有的问题。唯一缺少的方面是:
If the edge does not exist, it should be created.
因此,我将尝试使用稍微不同的查询来回答这一点。如果新边不存在,此查询将添加一条新边,然后更新/添加 weight
属性:
g.V(vertex.id()).outE('votes_for').has('type', 'eat')
.where(__.inV().hasLabel('meal').has('name','pizza')) // filter for the edge to update
.tryNext() // select the edge if it exists
.orElseGet({g.V(vertex.id()).next()
.addEdge('votes_for', g.V(pizzaId).next(), 'type', 'eat')}) // otherwise, add the edge
.property('weight', 0.99) // finally, update / add the 'weight' property