如何使用范围合并?
How to use coalesce with range?
使用 Grateful Dead 图:
g = TinkerFactory.createGratefulDead().traversal()
我想先尝试一个 range
,如果没有结果,return 另一个 range
:
gremlin> g.V().
......1> coalesce(
......2> range(900,909),
......3> range(0,9)
......4> )
我的预期是第一个 range
找不到任何东西,因为该图只有 808 个顶点,所以它会 return 前 10 个项目。但是,它 return 包含所有 808 个顶点,并且似乎忽略了 range
。我应该如何构造它?
您 coalesce()
的想法不对。请记住,您正在处理流经 Gremlin 管道的“事物”流。在您的示例中,您从 g.V()
开始,它迭代图中的所有顶点。 coalesce()
将在每个顶点上调用。 coalesce()
旨在 return 产生输出的第一个遍历参数的结果。第一个将失败,第二个将成功并输出当前顶点,因为它适合 0 到 9 的范围。如果你 profile()
:
你可以看到它的实际效果
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().coalesce(range(10,20),range(0,1))
==>v[1]
==>v[2]
==>v[3]
==>v[4]
==>v[5]
==>v[6]
gremlin> g.V().coalesce(range(10,20),range(0,1)).profile()
==>Traversal Metrics
Step Count Traversers Time (ms) % Dur
=============================================================================================================
TinkerGraphStep(vertex,[]) 6 6 0.565 66.10
CoalesceStep([[RangeGlobalStep(10,20)], [RangeG... 6 6 0.290 33.90
RangeGlobalStep(10,20) 0.036
RangeGlobalStep(0,1) 6 6 0.047
>TOTAL - - 0.855 -
不确定是否有另一种方法可以做到这一点,但在我的脑海中,我认为你必须实现一个带有 fold()
的列表,这样你就可以迭代它以查看你是否 运行 out of items 然后如果你再次迭代它:
gremlin> g.V().fold().coalesce(range(local,10,20).unfold(),range(local,0,1).unfold())
==>v[1]
gremlin> g.V().fold().coalesce(range(local,10,20).unfold(),range(local,0,2).unfold())
==>v[1]
==>v[2]
gremlin> g.V().fold().coalesce(range(local,5,6).unfold(),range(local,0,2).unfold())
==>v[6]
使用 fold()
可能会付出一些代价,因为您需要在内存中实现该列表。另一种选择可能是做这样的事情:
gremlin> g.V().order().by(id).range(10,20).fold().coalesce(unfold(),V().order().by(id).range(0,2))
==>v[1]
==>v[2]
gremlin> g.V().order().by(id).range(5,6).fold().coalesce(unfold(),V().order().by(id).range(0,2))
==>v[6]
如果您可以强制执行图形(取决于您使用的图形)将优化的顺序,那么您只会在内存中实现一个小得多的列表。
使用 Grateful Dead 图:
g = TinkerFactory.createGratefulDead().traversal()
我想先尝试一个 range
,如果没有结果,return 另一个 range
:
gremlin> g.V().
......1> coalesce(
......2> range(900,909),
......3> range(0,9)
......4> )
我的预期是第一个 range
找不到任何东西,因为该图只有 808 个顶点,所以它会 return 前 10 个项目。但是,它 return 包含所有 808 个顶点,并且似乎忽略了 range
。我应该如何构造它?
您 coalesce()
的想法不对。请记住,您正在处理流经 Gremlin 管道的“事物”流。在您的示例中,您从 g.V()
开始,它迭代图中的所有顶点。 coalesce()
将在每个顶点上调用。 coalesce()
旨在 return 产生输出的第一个遍历参数的结果。第一个将失败,第二个将成功并输出当前顶点,因为它适合 0 到 9 的范围。如果你 profile()
:
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().coalesce(range(10,20),range(0,1))
==>v[1]
==>v[2]
==>v[3]
==>v[4]
==>v[5]
==>v[6]
gremlin> g.V().coalesce(range(10,20),range(0,1)).profile()
==>Traversal Metrics
Step Count Traversers Time (ms) % Dur
=============================================================================================================
TinkerGraphStep(vertex,[]) 6 6 0.565 66.10
CoalesceStep([[RangeGlobalStep(10,20)], [RangeG... 6 6 0.290 33.90
RangeGlobalStep(10,20) 0.036
RangeGlobalStep(0,1) 6 6 0.047
>TOTAL - - 0.855 -
不确定是否有另一种方法可以做到这一点,但在我的脑海中,我认为你必须实现一个带有 fold()
的列表,这样你就可以迭代它以查看你是否 运行 out of items 然后如果你再次迭代它:
gremlin> g.V().fold().coalesce(range(local,10,20).unfold(),range(local,0,1).unfold())
==>v[1]
gremlin> g.V().fold().coalesce(range(local,10,20).unfold(),range(local,0,2).unfold())
==>v[1]
==>v[2]
gremlin> g.V().fold().coalesce(range(local,5,6).unfold(),range(local,0,2).unfold())
==>v[6]
使用 fold()
可能会付出一些代价,因为您需要在内存中实现该列表。另一种选择可能是做这样的事情:
gremlin> g.V().order().by(id).range(10,20).fold().coalesce(unfold(),V().order().by(id).range(0,2))
==>v[1]
==>v[2]
gremlin> g.V().order().by(id).range(5,6).fold().coalesce(unfold(),V().order().by(id).range(0,2))
==>v[6]
如果您可以强制执行图形(取决于您使用的图形)将优化的顺序,那么您只会在内存中实现一个小得多的列表。