问题描述
我正在尝试编写一个 Gremlin 遍历,意思是“将所有这些身份添加到这个组中”,在 the "inject list" example in the recipes 之后对其进行模式化。这是我正在尝试的逻辑:
List identityIds = [...]
gts.inject(identityIds).unfold()
.V() // filter statement goes here?
.addE(GROUP_INCLUDES_IDENTITY).from(V(groupId))
.iterate()
据我所知,这将为列表中的每个元素生成一个遍历器并执行 addE
操作。但是,我无法弄清楚如何在遍历中表达 V().hasId(it)
。 identity()
步骤似乎应该适用,但我不能将其用作 V
或 hasId
的参数。
我曾尝试使用 unfold().as("id")
来形成表达式,但我遇到了同样的问题,即 select()
返回遍历并且我无法在明显的地方使用遍历。
解决方法
您可以使用 where()
做您想做的事:
gremlin> g.inject(1,2).as('id').
......1> V().as('v').
......2> where('id',eq('v')).
......3> by().by(id)
==>v[1]
==>v[2]
但这并不理想,因为不太可能优化此遍历以使用索引。
我认为此时最好的方法是使用 V(identityIds)
。您提到了一个更复杂的案例,而且这个复杂案例通常与想要传递带有 id(通常是属性)的额外数据有关,在这种情况下,我仍然会坚持使用 V(identityIds)
并简单地将这些额外数据视为一面-效果:
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6],standard]
gremlin> data = [[i: 1,w: 0.99],[i: 2,w: 0.98]]
==>[i:1,w:0.99]
==>[i:2,w:0.98]
gremlin> g.withSideEffect('d',data).
......1> V(data.collect{it.i}).as('v').
......2> addE('knows').to(V(6)).as('e').
......3> select('d').unfold().as('p').
......4> where('p',eq('v')).
......5> by('i').by(id).as('weight').
......6> select('e').
......7> property('weight',select('weight'))
==>e[13][1-knows->6]
==>e[14][2-knows->6]
gremlin> g.E(13,14).elementMap()
==>[id:13,label:knows,IN:[id:6,label:person],OUT:[id:1,weight:[i:1,w:0.99]]
==>[id:14,OUT:[id:2,weight:[i:2,w:0.98]]
可能有更好的写法,但总体思路是确保使用 V(ids)
命中顶点查找的索引,然后将要使用的数据视为某种侧面 -您必须将顶点 id 与效果匹配,然后使用 Map
手头,您可以更新您想要的任何属性。此 blog post 更详细地描述了用于插入的一般方法。