最好提供一个 Gremlin 脚本来生成一些示例数据,因为它可以使问题的上下文更加清晰:
g.addV('u').as('u').
addV('v').property('name','name1').as('v1').
addV('v').property('name','name2').as('v2').
addV('v').property('name','name1').as('v3').
addE('label1').from('u').to('v1').
addE('label2').from('u').to('v1').
addE('label1').from('u').to('v2').
addE('label2').from('u').to('v2').
addE('label2').from('u').to('v3').iterate()
在这种情况下,我假设您只想获得我在上面标记为“v1”的顶点,因为它是唯一一个具有两条边(一个标记为“label1”,一个标记为“label2”)并且具有属性键“name1”。我进一步假设您的图形的模式将只允许边的奇异多重性,这样您在“u”和“v*”顶点之间将有零个或一个“label1”和“label2”边。
我采用了这种方法,但可能还有其他方法:
gremlin> g.V().hasLabel('u').
......1> outE('label1','label2').
......2> where(otherV().has('name','name1')).
......3> groupCount().
......4> by(otherV()).
......5> unfold().
......6> where(select(values).is(eq(2))).
......7> select(keys).
......8> unfold().
......9> valueMap(true)
==>[id:1,name:[name1],label:v]
这里的要点是考虑groupCount(),它基本上给出了连接到otherV() 的边数。您希望它们等于 2 以使过滤器成功。因此,在groupCount() 之后,生成的Map 包含键的otherV() 和值的边数展开到条目并在第6 行过滤。一旦我们有了,我们就可以从Map 因为我们不再需要计数了。
我还尝试了 match(),我认为 CosmosDB 不支持它,但在这种情况下实际上读起来非常好:
gremlin> g.V().hasLabel('u').
......1> match(__.as('u').out('label1').as('v'),
......2> __.as('u').out('label2').as('v'),
......3> __.as('v').has('name','name1')).
......4> select('v').
......5> by(valueMap(true))
==>[id:1,name:[name1],label:v]