Gremlin API:如何遍历顶点,有条件地收集属性,并在收集的属性达到一定限制时停止



我是图形和Gremlin API的新手,尽管我发现它对我的目的很有前途,所以我正在调查,尽管我看了文档和几个教程,但似乎找不到如何做到这一点。

我的图的一部分将具有表示";文档";用";id";(1,2,3,…(和";作者"(a:Luc,Kim,…(财产。它们与简单的";下一个";边缘。像这样:

V1{a:'Luc'} -> V2{a:'Kim'} -> V3{a:'Marc'} -> V4{a:'Kim'} -> V5{a:'Luc'} -> V6{a:'Luc'}

我想做的事:

  • 从垂直id的任何已知位置开始(例如:V(2((
  • 要么去";向上";带有in((或";向下";带out(((例如:out(((
  • 不知怎的";收集";将其作者部分作为数组的顶点的id(例如:["Luc","Kim"](
  • 继续进行,直到我最多收集了一定数量的id(在大多数情况下,这将小于我要遍历以收集它们的顶点的数量(,或者直到我到达终点(例如:最大3(

所以对于这个例子,我希望结果是:[2,4,5]。

根据我目前的发现,我会有这样的东西:

g.V(2).repeat(somethingThatKeepsTheIdIfAuthorIsInArray(['Luc', 'Kim']).out()).until("I have found 3 ids")

或者,如果我用不同的措辞,我想";跳过";顶点3,因为它的作者不在列表中,但继续进行,直到我找到最多3个符合我的条件的顶点,或者我到达然后结束。

你知道我应该采取什么步骤来实现这一点吗?

我一直在挖掘,发现这是一个可能的解决方案:

g.v('D2').emit(has('author', within('Luc', 'Kim'))).repeat(out()).limit(3).values('id').fold()

哪个收益率:

['D2', 'D4', 'D5']

我还确认,无论我们从哪个顶点开始,它都能正确工作。例如,启动D5会产生:

['D5', 'D6']

我唯一关心的(问题(是如何应用限制(3(?当发射3个顶点时,它是否真的中断了重复循环,或者重复循环将遍历所有顶点;下一个";边,然后截断结果,只返回3?

使用此图

g.addV('Document').property('author','Luc').property(id,'D1').as('d1').
addV('Document').property('author','Kim').property(id,'D2').as('d2').
addV('Document').property('author','Marc').property(id,'D3').as('d3').
addV('Document').property('author','Kim').property(id,'D4').as('d4').
addV('Document').property('author','Luc').property(id,'D5').as('d5').
addV('Document').property('author','Luc').property(id,'D6').as('d6').
addE('NEXT').from('d1').to('d2').
addE('NEXT').from('d2').to('d3').
addE('NEXT').from('d3').to('d4').
addE('NEXT').from('d4').to('d5').
addE('NEXT').from('d5').to('d6') 

我们可以编写一个Gremlin查询,测试特定作者的姓名,并使用sideEffect来存储匹配的姓名。


g.V('D2').
repeat(out('NEXT').sideEffect(has('author',within('Luc','Kim')).id().store('documents'))).
until(not(out('NEXT'))).
select('documents')

哪个将返回

['D4', 'D5', 'D6']

只要对查询进行一点更改,我们还可以测试最大数量的文档。

g.V('D2').
repeat(out('NEXT').
sideEffect(has('author',within('Luc','Kim')).id().store('documents'))).
until(not(out('NEXT')).or().select('documents').count(local).is(2)).
select('documents')

产生

['D4', 'D5']

为了在结果中包括起始顶点,我们可以在repeat步骤中将sideEffect放在第一位。

g.V('D2').
repeat(out('NEXT').
sideEffect(has('author',within('Luc','Kim')).id().store('documents'))).
until(not(out('NEXT')).or().select('documents').count(local).is(2)).
select('documents')

产生

['D2', 'D4', 'D5']

更新2021-11-17

为了回应下面的评论/讨论,这里还有两个正在使用的查询示例。第一个从D2开始,带有is(3),第二个从D4开始。这些是使用Gremlin控制台和TinkerGraph运行的。虽然我的查询有效,但既然我完全理解了您的需求,我认为它对您的情况有点过于设计了。我认为你发布的答案对这个案子来说是好的。需要注意的是,正如我们在评论中所讨论的,您的查询在大多数支持TinkerPop的商店中都会失败,但在CosmosDB上似乎正以您需要的方式工作。我投票支持你的答案:-(

gremlin> g.V('D2').
......1>   repeat(out('NEXT').
......2>          sideEffect(has('author',within('Luc','Kim')).id().store('documents'))).
......3>   until(__.not(out('NEXT')).or().select('documents').count(local).is(3)).
......4>   select('documents')   
==>[D4,D5,D6]   

gremlin> g.V('D4').
......1>   repeat(out('NEXT').
......2>          sideEffect(has('author',within('Luc','Kim')).id().store('documents'))).
......3>   until(__.not(out('NEXT')).or().select('documents').count(local).is(3)).
......4>   select('documents')     
==>[D5,D6]  

最新更新