Dou*_*e M 7 gremlin titan tinkerpop3
我有一个足够简单的任务来完成:设置特定边缘属性的权重.以此场景为例:
我想做的是更新值weight
.
其他要求
type
Joey和Pizza之间不能存在多个"吃" 的"吃"的边缘.我有以下信息:
我想我需要做类似以下的事情:
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?
Run Code Online (Sandbox Code Playgroud)
正如在代码中评论的那样,仍然存在问题.明确指定Titan架构会有帮助吗?有没有我不知道的帮助/实用方法?拥有多个vote_for
标签而不是一个标签+ type
属性更合理vote_for_eat
吗?
谢谢你的帮助!
你走在正确的轨道上.查看顶点步骤文档.
标记边缘,然后从边缘遍历到顶点进行检查,然后跳回边缘以更新属性.
g.V(vertex.id()).
outE("votes_for").has("type", "eat").as("e").
inV().has("name", "pizza").
select("e").property("weight", 0.99d).
iterate()
Run Code Online (Sandbox Code Playgroud)
完整的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]
Run Code Online (Sandbox Code Playgroud)
明确指定Titan架构会有帮助吗?
如果你想从Joey
节点开始而没有引用它vertex
或它id
,那么这将是Titan 复合索引的一个很好的用例.遍历将从以下开始:
g.V().has("given_name", "Joey")
Run Code Online (Sandbox Code Playgroud)
有没有我不知道的帮助/实用方法?
除了TinkerPop参考文档之外,您还可以阅读以下几个教程:
拥有几个vote_for标签而不是一个标签+类型属性(如vote_for_eat)会更有意义吗?
取决于您的图形模型或查询模式是什么,但更细粒度的标签vote_for_eat
可以很好地解决.您可以在遍历步骤上传递多个边缘标签:
g.V(vertex.id()).outE('vote_for_eat', 'vote_for_play', 'vote_for_sleep')
Run Code Online (Sandbox Code Playgroud)
更新
两个节点之间可能最多只存在相同类型的一个边缘
您可以使用Titan架构来帮助解决此问题,特别是定义具有多重性 的边缘标签ONE2ONE
.如果votes_for_eat
在Joey
和之间创建多个,则会抛出异常pizza
.
Jason 已经回答了您几乎所有的问题。唯一缺少的方面是:
如果边不存在,则应创建它。
所以我会尝试用一个稍微不同的查询来回答这一点。如果新边不存在,此查询会添加新边,然后更新/添加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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6462 次 |
最近记录: |