我是图形和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]