如何在 Gremlin 中执行分页

How to perform pagination in Gremlin

Tinkerpop 3中,如何进行分页?我想获取查询的前 10 个元素,然后获取接下来的 10 个元素,而不必将它们全部加载到内存中。比如下面查询returns1000,000条记录。我想 10 乘 10 地获取它们,而不是一次加载所有 1000,000 个。

g.V().has("key", value).limit(10)

编辑

通过 HttpChannelizer 在 Gremlin 服务器上运行的解决方案将是理想的。

从功能的角度来看,用于分页的 Gremlin 看起来不错:

gremlin> g.V().hasLabel('person').fold().as('persons','count').
               select('persons','count').
                 by(range(local, 0, 2)).
                 by(count(local))
==>[persons:[v[1],v[2]],count:4]
gremlin> g.V().hasLabel('person').fold().as('persons','count').
               select('persons','count').
                 by(range(local, 2, 4)).
                 by(count(local))
==>[persons:[v[4],v[6]],count:4]

通过这种方式,您可以获得顶点的总数以及结果。不幸的是,fold() 强制您计算所有需要迭代它们的顶点(即将它们全部放入内存)。

在这种情况下确实无法避免迭代所有 100,000 个顶点,只要您打算在多个单独的尝试中执行遍历。例如:

gremlin> g.V().hasLabel('person').range(0,2)
==>v[1]
==>v[2]
gremlin> g.V().hasLabel('person').range(2,4)
==>v[4]
==>v[6]

第一个语句与使用 limit(2) 终止遍历相同。在第二次遍历中,只需要后两个顶点,这并不是你神奇地跳过前两个顶点的迭代,因为它是一个新的遍历。我不知道有任何 TinkerPop 图数据库实现可以有效地做到这一点——它们都有这种行为。

一次处理十个顶点而不将它们全部存储在内存中的唯一方法是使用与以下相同的 Traversal 实例:

gremlin> t = g.V().hasLabel('person');[]
gremlin> t.next(2)
==>v[1]
==>v[2]
gremlin> t.next(2)
==>v[4]
==>v[6]

使用该模型,您只需迭代一次顶点,而不是在一个时间点将它们全部存入内存。

关于这个主题的一些其他想法可以在这个 blog post 中找到。

为什么不添加 order().by() 并在您的 gremlin 查询中执行 range() 函数。